微型計(jì)算機(jī)原理與接口技術(shù)(4)
單擊此處編輯母版標(biāo)題樣式,單擊此處編輯母版文本樣式,第二級(jí),第三級(jí),第四級(jí),第五級(jí),*,第四章 匯編語言程序設(shè)計(jì),匯編語言是利用指令的助記符、符號(hào)地址、標(biāo)號(hào)來編寫的語言,它是機(jī)器語言的符號(hào)表示,是較低級(jí)的語言。利用匯編語言編寫的程序稱為源程序,指令系統(tǒng)中的每條指令都是構(gòu)成源程序的基本語句。但機(jī)器不能識(shí)別源程序,要通過匯編程序翻譯成二進(jìn)制代碼的浮動(dòng)目標(biāo)程序,然后由連接程序?qū)⒛繕?biāo)文件與庫文件相連,最后得到可執(zhí)行的程序,才可在機(jī)器上直接運(yùn)行。,一個(gè)完整的匯編程序編寫格式要包括以下幾部分:段定義、段分配、設(shè)置段地址、返回DOS語句及程序結(jié)束,需要時(shí)加上過程調(diào)用。,(1)匯編語言編寫的原程序是分段的,要定義代碼段、數(shù)據(jù)段、堆棧段,每段由段定義偽指令SEGMENT開始,ENDS結(jié)束,并賦予段名區(qū)分不同段。段定義的基本格式如下:,段名 SEGMENT,段名 ENDS,原程序中至少有一個(gè)代碼段,此時(shí)數(shù)據(jù)可放在代碼段中;堆棧段如果不定義,由計(jì)算機(jī)自動(dòng)分配。段名可以自己定義,用字母和數(shù)字組成。計(jì)算機(jī)識(shí)別不同的段由段分配偽指令A(yù)SSUME來完成。段分配的格式為:,ASSUME CS:段名,DS:段名,SS:段名,ES:段名,(2)過程調(diào)用由偽指令PROCENDP實(shí)現(xiàn),過程的調(diào)用格式如下(也可省略):,過程名 PROC FAR(NEAR);FAR表示遠(yuǎn)調(diào)用,NEAR表示近調(diào)用可缺省,過程名 ENDP,(3)若程序已經(jīng)分別定義了數(shù)據(jù)段、堆棧段和附加段,主程序的開始要設(shè)置這些段的地址。代碼段的地址不能人為設(shè)置,由計(jì)算機(jī)分配。堆棧段和數(shù)據(jù)段設(shè)置的具體語句為;,MOV AX,STACK ;送堆棧段地址,MOV SS,AX,MOV AX,DATA ;送數(shù)據(jù)段地址,MOV DS,AX,(4)程序執(zhí)行完畢要返回DOS操作系統(tǒng),有兩種方式實(shí)現(xiàn)。一種是在程序的開始部分編寫如下語句:,PUSH DS,MOV AX,0,PUSH AX,將DS的內(nèi)容及0作為段地址和偏移地址入棧,在程序結(jié)束時(shí)返回DOS。以上三句語句必須寫在堆棧段設(shè)置后面,否則堆棧段的設(shè)置使一些指令不起作用了。第二種方法是在程序結(jié)束前使用DOS功能調(diào)用指令,如下所示:,MOV AX,4C00H,INT 21H,(5)全部源程序用END語句結(jié)尾,END后面可以加上程序執(zhí)行起始的名稱START,匯編程序遇見END語句就結(jié)束。,4.1 匯編語言程序格式,8086系統(tǒng)中常用的匯編程序是MASM6.X版本,MASM中可使用的語句分成兩類:指令性語句和偽指令語句。,一、指令性語句,指令性語句與機(jī)器指令相對(duì)應(yīng),匯編程序可將它翻譯成目標(biāo)代碼(機(jī)器指令代碼)。語句格式為:,標(biāo)號(hào):指令助記符 操作數(shù),操作數(shù) ;注釋,標(biāo)號(hào)表示本指令語句的符號(hào)地址,標(biāo)號(hào)后面必須緊跟冒號(hào)“:”。,指令助記符是該語句的指令名稱的代表符號(hào),它指出指令的操作類型,匯編程序?qū)⑵浞g成機(jī)器指令。它是語句中的關(guān)鍵字,因此不可省略。,操作數(shù)表示參加本指令運(yùn)算的數(shù)據(jù),根據(jù)指令要求可以有一個(gè)或多個(gè)操作數(shù),有的指令不需要操作數(shù),多個(gè)操作數(shù)之間用逗號(hào)“,”隔開,操作數(shù)與指令助記符之間用空格隔開。操作數(shù)可以是常數(shù)、變量、標(biāo)號(hào)、寄存器名或表達(dá)式。,二、偽指令語句,偽指令語句沒有對(duì)應(yīng)的機(jī)器指令,匯編程序匯編源程序時(shí)對(duì)偽指令進(jìn)行處理,它可完成數(shù)據(jù)定義,存儲(chǔ)區(qū)分配,段定義,段分配,指示程序結(jié)束等功能。偽指令語句的格式為:,名字 偽指令指示符 操作數(shù),操作數(shù) ;注釋,名字是給偽指令取的名稱,它用符號(hào)地址表示,名字后不允許帶冒號(hào)“:”,名字可以省略。偽指令中的名字通常是變量名、段名、過程名、符號(hào)名等。,偽指令指示符是匯編程序MASM規(guī)定的符號(hào),常用的有變量定義語句(DB、DW),符號(hào)定義語句(EQU、),段定義語句(SEGMENT.ENDS),段分配語句(ASSUME),結(jié)構(gòu)定義語句(STURC.ENDS),過程定義語句(PROR.ENDP)等類型,后面將詳細(xì)說明。,操作數(shù)是由偽指令具體要求的,有的偽指令不允許帶操作數(shù),有的偽指令要求帶多個(gè)操作數(shù),多個(gè)操作數(shù)之間必須用逗號(hào)分開。操作數(shù)可以是常數(shù)、變量、字符串、表達(dá)式等。,三、數(shù)據(jù)項(xiàng),匯編語言中使用的操作數(shù),可以是常數(shù),寄存器、存儲(chǔ)器、變量、標(biāo)號(hào)或表達(dá)式,其中常數(shù)、變量和標(biāo)號(hào)是三種基本數(shù)據(jù)項(xiàng)。,1常數(shù),常數(shù)必須是固定值,沒有屬性,是確定的數(shù)據(jù)。,2變量,變量通常指存放在存儲(chǔ)單元中的值,在程序運(yùn)行中是可以修改的。所有的變量都具有三個(gè)屬性。,(1)段值(SEGMENT)指變量所在段的段基址。,(2)段內(nèi)偏移地址(OFFSET):指變量地址與所在段首地址之間的地址偏移字節(jié)數(shù)。,(3)類型(TYPE):變量的類型屬性指變量中每個(gè)元素所包含的字節(jié)數(shù),類型有:字節(jié)變量(BYTE)、宇變量(WORD)及雙字變量(DWORD)等。,3標(biāo)號(hào),標(biāo)號(hào)是可執(zhí)行指令語句的地址的符號(hào)表示,它可作為轉(zhuǎn)移指令的目標(biāo)操作數(shù),以確定程序轉(zhuǎn)向的目標(biāo)地址,它具有三個(gè)屬性。,(1)段值(SEGMENT):標(biāo)號(hào)所在段的段基址。,(2)段內(nèi)偏移地址(OFFSET):標(biāo)號(hào)地址與所在段的段首址之間的偏移地址字節(jié)數(shù)。,(3)類型(TYPE):標(biāo)號(hào)的類型屬性指在轉(zhuǎn)移指令中標(biāo)號(hào)可轉(zhuǎn)移的距離,也稱距離屬性。類型NEAR,表示此標(biāo)號(hào)為近標(biāo)號(hào),只能實(shí)現(xiàn)本代碼段內(nèi)轉(zhuǎn)移或調(diào)用,類型FAR,表示此標(biāo)號(hào)為遠(yuǎn)標(biāo)號(hào),可以作為其它代碼段中的目標(biāo)地址,實(shí)現(xiàn)段間轉(zhuǎn)移或調(diào)用。若標(biāo)號(hào)后面緊跟冒號(hào),表示隱含此標(biāo)號(hào)距離屬性為NEAR,也可用偽指令將此屬性改為FAR。,4.2 MASM中的表達(dá)式,一、算術(shù)運(yùn)算符,加、減、乘、除、MOD、SHL、SHR。運(yùn)算對(duì)象與運(yùn)算結(jié)果都是整數(shù)。,二、邏輯運(yùn)算符,邏輯運(yùn)算符包括AND(與)、OR(或)、NOT(非),XOR(異或)4種,邏輯運(yùn)算符是按位運(yùn)算的,只能對(duì)常數(shù)進(jìn)行運(yùn)算,得到結(jié)果也是常數(shù)。,三、關(guān)系運(yùn)算符,關(guān)系運(yùn)算符包括EQ(相等)、NE(不等)、LT(小于)、GT(大于)、LE(小于或等于)、GE(大于或等于)6種。,關(guān)系運(yùn)算符的兩個(gè)操作數(shù)必須是數(shù)據(jù),或是同一段內(nèi)的兩個(gè)存儲(chǔ)單元的地址。進(jìn)行關(guān)系運(yùn)算的比較操作后,結(jié)果是一個(gè)數(shù)值,若結(jié)果為真,輸出全是l,即,0FFH或0FFFFH。若結(jié)果為假,輸出全是0。關(guān)系運(yùn)算符一般與邏輯運(yùn)算符組合起來使用。,四、數(shù)值返回運(yùn)算符,1OFFSET,格式:OFFSET變量或標(biāo)號(hào),OFFSET返回標(biāo)號(hào)或變量的偏移地址值。,2SEG,格式:SEG變量或標(biāo)號(hào),SEG用來取變量或標(biāo)號(hào)的段基值。,3TYPE,格式:TYPE 變量或標(biāo)號(hào),TYPE加在變量前,返回變量的類型屬性,TYPE加在標(biāo)號(hào)前,返回標(biāo)號(hào)的距離屬性。,4LENGTH,格式:LENGTH 變量,當(dāng)變量中使用DUP時(shí),LENGTH返回此變量所包含的單元數(shù),對(duì)其它變量則返回1。,5.SIZE,格式:SIZE變量,SIZE運(yùn)算符加在變量前,返回該變量包含的總字節(jié)數(shù)。,SIZELENGTHTYPE,五、修改屬性運(yùn)算符,1.段操作符,格式:段前綴:變量或地址表達(dá)式,段前綴有段寄存器CS、DS、ES、SS后跟冒號(hào)“:”,用來表示某個(gè)變量或地址被修改到哪個(gè)段寄存器提供的段基址中。,2PTR,格式:類型/距離 PTR 變量或標(biāo)號(hào),其功能是將PTR左邊的類屬性賦給右邊的變量或標(biāo)號(hào)。PTR本身并不分配存儲(chǔ)單元,僅給已分配的存儲(chǔ)單元賦予新的屬性,以保證運(yùn)算時(shí)操作數(shù)類型的匹配,常與類型BYTE、WORD、NEAR、FAR等連用。,3THIS,格式:變量/標(biāo)號(hào) EQU THIS 類型/距離,THIS的功能是將EQU THIS右邊的類型/距離屬性,賦給左邊的變量/標(biāo)號(hào),該變量或標(biāo)號(hào)的段地址和偏移地址與下一個(gè)存儲(chǔ)單元的地址相同。,4SHORT,格式:SHORT標(biāo)號(hào),SHORT用來說明轉(zhuǎn)移類指令中轉(zhuǎn)向地址的屬性,指出轉(zhuǎn)向的目標(biāo)地址與本指令之間的距離在128127之間,即限制在短轉(zhuǎn)移范圍內(nèi)。,5HIGH和LOW,格式:H1GH/LOW變量或標(biāo)號(hào),HIGH和LOW稱為字節(jié)分離運(yùn)算符,對(duì)一個(gè)數(shù)或地址表達(dá)式,HIGH從中分離出高位字節(jié),LOW分離出低位字節(jié)。,六、其它運(yùn)算符,1圓括號(hào)(),圓括號(hào)用來改變運(yùn)算符的優(yōu)先級(jí)別,()中的運(yùn)算符具有最高優(yōu)先權(quán)。,2方括號(hào) ,方括號(hào)主要用來表示地址表達(dá)式或多重變量的下標(biāo)值。,3尖括號(hào),及圓點(diǎn),運(yùn)算符在結(jié)構(gòu)中專用,表示結(jié)構(gòu)中的變量在預(yù)置結(jié)構(gòu)付本時(shí)是否修改,修改成什么數(shù)值。,運(yùn)算符在結(jié)構(gòu)中專用,表示結(jié)構(gòu)付本名與變量名連接在一起,作為預(yù)置的結(jié)構(gòu)付本中的各個(gè)變量。,4MASK和WIDTH,MASK與WIDTH運(yùn)算符在記錄中專用。,WIDTH為記錄名/字段名,運(yùn)算后返回?cái)?shù)值表示指定記錄或字段的位的長(zhǎng)度。,MASK為字段名,返回?cái)?shù)值為8位/16位二進(jìn)制數(shù),對(duì)應(yīng)指定字段的各位置“1”,其它位置“0”。,七、優(yōu)先級(jí),4.3 偽指令語句,一、數(shù)據(jù)定義語句,格式1:變量名 助記符 操作數(shù),操作數(shù) ;注釋,格式2:變量名 助記符 n DUP(操作數(shù),操作數(shù));注釋,功能:將操作數(shù)存入變量名指定的存儲(chǔ)單元中,或者只分配存儲(chǔ)空間不存入數(shù)據(jù)。,變量名它用符號(hào)表示,可以省略,作用與指令語句中的標(biāo)號(hào)相同,但后面不跟冒號(hào)。匯編程序匯編時(shí)將此變量的助記符后的第一個(gè)字節(jié)的偏移地址作為它的符號(hào)地址。,助記符所用偽指令助記符主要有:,DB:用來定義字節(jié),表示每個(gè)操作數(shù)占用一個(gè)字節(jié)。,DW;用來定義字,表示每個(gè)操作數(shù)占用一個(gè)字。,DD:用來定義雙字,表示每個(gè)操作數(shù)占用兩個(gè)字。,DQ:用來定義四個(gè)字,表示每個(gè)操作數(shù)占用四個(gè)字。,DT:用來定義十個(gè)字節(jié),表示每個(gè)操作數(shù)占用十個(gè)字節(jié)。,二、表達(dá)式賦值語句,表達(dá)式賦值語句有兩種,賦值語句EQU和等號(hào)語句,它們均不占用內(nèi)存。,1賦值語句EQU,格式:符號(hào)名 EQU 表達(dá)式,功能:用來給變量,標(biāo)號(hào),常數(shù),指令,表達(dá)式等定義一個(gè)符號(hào)名,程序中用到EQU左邊的變量、標(biāo)號(hào)時(shí)可用右邊的常數(shù)值或表達(dá)式代替,但一經(jīng)定義在同一個(gè)程序模塊中不能重新定義。,2等號(hào)語句,等號(hào)語句“”與EQU語句具有相同功能,區(qū)別僅在于EQU中左邊的標(biāo)號(hào)不允許重新定義,而用“”定義的語句允許重復(fù)定義。,三、段定義語句,1.段定義語句SEGMENTENDS,格式:段名 SEGMENT 定位類型 組合類型 分類名,邏輯段內(nèi)容,段名 ENDS,功能:將一個(gè)邏輯段定義成一個(gè)整體。,段定義語句中的參數(shù)設(shè)置,可以增強(qiáng)偽指令語句的功能。段定義語句允許嵌套設(shè)置,即一個(gè)邏輯段內(nèi)再設(shè)置其它邏輯段,但不允許各個(gè)邏輯段相互交叉設(shè)置。,2.段分配語句(ASSUME),在8086/8088系統(tǒng)中存儲(chǔ)器采用分段結(jié)構(gòu),各段容量64KB,用戶可以設(shè)置多個(gè)邏輯段,但只允許4個(gè)邏輯段同時(shí)有效,段分配語句用來完成將邏輯段分別定義成代碼段,數(shù)據(jù)段,堆棧段及附加段。,格式:ASSUME CS:段名,DS:段名,SS:段名,ES:段名,功能:定義4個(gè)邏輯段,指明段與段寄存器的關(guān)系。,ASSUME NOTHING 可以取消前面由ASSUME所指定的段寄存器。,例:兩個(gè)16位無符號(hào)二進(jìn)制數(shù)相乘。,DATA SEGMENT,D1 DW 1234H,D2 DW 5678H,P1 DD?,P2 DD?,DATA ENDS,STACK SEGMENT STACK STACK,DW 100 DUP(?),STACK ENDS,CODE SEGMENT,ASSUME CS:CODE,DS:DATA,SS:STACK,MAIN PROC FAR,START:MOV AX,STACK,MOV SS,AX,PUSH DS,SUB AX,AX,PUSH AX,MOV AX,DATA,MOV DS,AX,L1:MOV AX,D1,MUL D2,MOV BX,OFFSET P1,MOV BX,AX,MOV BX+2,DX,RET,MAIN ENDP,CODE ENDS,END START,四、過程定義語句,過程也稱作子程序。在主程序中,經(jīng)常要用到一些程序段,程序段的功能和結(jié)構(gòu)相同,僅有一些變量賦值不同,此時(shí)可以將這些程序段獨(dú)立編寫,用過程定義語句進(jìn)行定義,然后在主程序中對(duì)它進(jìn)行過程調(diào)用。,格式:過程名