第四章偽指令_第1頁
第四章偽指令_第2頁
第四章偽指令_第3頁
第四章偽指令_第4頁
第四章偽指令_第5頁
已閱讀5頁,還剩33頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、第四章 偽指令匯編語言源程序由一系列語句構成,這些語句既可以是指令,也可以是偽指令。指令是由CPU負責執(zhí)行的,每一條指令都和一條機器語言相對應。而偽指令是由匯編程序負責執(zhí)行,完成一些內存單元分配、段之間的連接關系等操作,所以偽指令并不會生成機器指令,也就不會被CPU執(zhí)行。在本章中,重點講解一些常用的偽指令及其功能。4.1偽指令的分類及偽指令語句格式偽指令又稱為偽操作,它雖然不會被CPU執(zhí)行,但卻可以指示匯編程序按照用戶的意圖,完成數(shù)據(jù)的定義、存儲器的分配、指示程序結束等功能。所以偽指令在匯編語言程序設計過程中具有重要的意義,希望讀者在學習過程中應該加以高度重視。4.1.1 偽指令的分類8088

2、/8086的偽指令大致可分為以下八類:·數(shù)據(jù)定義偽指令;·符號定義偽指令;·段定義偽指令;·過程定義偽指令;·結束偽指令;·條件匯編偽指令;·結構、記錄定義偽指令;·其他偽指令。其中,條件匯編偽指令與結構、記錄定義偽指令將在第八章予以介紹。4.1.2 偽指令語句格式偽指令語句格式一般由四部分組成。語句格式: 變量 偽指令助記符 參數(shù)1,參數(shù)2····參數(shù)n;注釋說明:偽指令助記符規(guī)定了偽指令的功能。一般偽指令都有參數(shù),用于說明偽指令的操作對象,參數(shù)的類型和個數(shù)隨著偽指令的不同

3、而不同。有時參數(shù)是常數(shù)或數(shù)值表達式,有時參數(shù)是一般的符號,有時是具有特殊意義的符號。偽指令語句中的變量可有可無,如果偽指令語句中出現(xiàn)變量,則匯編程序使其記以第一個字節(jié)的偏移地址。注釋部分也是可有可無的,用于說明該偽指令的功能。例如 VAR1 DW 1234H,5678H ;定義VAR1為字變量該語句中的VAR1為變量;DW為偽指令助記符;1234H與5678H為參數(shù);分號后面給出的文字為注釋。4.2匯編語言中的數(shù)據(jù)項數(shù)據(jù)項是指令或偽指令語句操作對象的基本組成部分。一個數(shù)據(jù)項包含有數(shù)值和屬性兩部分,這兩部分對一條語句匯編成機器目標代碼有著直接關系。通常,匯編語言能識別的數(shù)據(jù)項有:常數(shù)、變量和標號

4、。8086/8088匯編語言還采用了很有用的數(shù)據(jù)結構形式,例如結構和記錄,可以被看成是兩種特殊的變量。4.2.1 常數(shù)常數(shù)是沒有任何屬性的純數(shù)值。在匯編期間,它的值已被完全確定,且在程序運行過程中,它也不會發(fā)生變化。常數(shù)可以有以下類型:1 二進制以字母B結尾的由0和1組成的數(shù)字序列。如10100011B。2 八進制以字母O或Q結尾的由07組成的數(shù)字序列。如345Q。3 十進制以字母D結尾的由09組成的數(shù)字序列。如7825D。4 十六進制以字母H結尾的由09和AF組成的數(shù)字序列。如12FFH。5 字符串常數(shù)用單引號或雙引號括起來的一個或多個字符。這些字符以其ASCII碼形式存儲在內存中。如A,在

5、內存中就是41H,如果是“AB”就是41H和42H組合。說明:(1) 在程序中,常數(shù)主要出現(xiàn)在以下三個地方:在指令語句的源操作數(shù)中作立即數(shù)使用,它應與目的操作數(shù)的位數(shù)一致,可以是8位或16位的。例如:MOV AL,00001111BADD DX,0ABCDHMOV AL,A在指令語句的mem表達式中作位移量。例如:MOV AX,44HSIMOV DX,1234HBXSI在偽指令定義數(shù)據(jù)語句中出現(xiàn)。例如:DB 12H ;定義一個字節(jié)數(shù)據(jù),值為12HDB “ABCD” ;定義四個字節(jié)的字符串數(shù)據(jù),值為41H、42H、43H和44HDD 12345678H ;定義一個雙字數(shù)據(jù),長度為32位,值為12

6、345678HPRICE EQU 30H ;符號PRICE等價于30H(2) 在匯編程序中,默認基數(shù)是十進制數(shù),即在語句中出現(xiàn)的十進制常數(shù)可以不在末尾加字符D,如十進制常數(shù)123D 可以寫為123。當然我們可以使用“.RADIX”偽指令改變默認的基數(shù)。例如:.RADIX 16 ;將默認基數(shù)改變?yōu)?6進制.RADIX 2 ;將默認基數(shù)改變?yōu)?進制4.2.2 變量變量是代表存放在某些存儲單元的符號。這些符號所代表的數(shù)據(jù)在程序運行期間隨時可能變化。為了便于對變量的訪問,它常常以變量名的形式出現(xiàn)在程序中。變量也包含數(shù)值和屬性兩部分。1. 變量的定義與預置定義變量就是給變量分配存儲單元,且對這個存儲單元

7、賦予一個符號名,即變量名,同時將這些存儲單元預置初值。定義變量是用數(shù)據(jù)定義偽指令DB、DW、DD、DQ、DT等實現(xiàn)的。例如:DSEG SEGMENTVAR1 DB 12HVAR2 DB 20HVAR3 DW 1234HDSEG ENDS經過定義的變量都有三個屬性:段屬性、偏移屬性和類型屬性。(1)段屬性(SEG)它表示變量存放在哪一個邏輯段中(即變量所在段的段首址)。例如變量VAR1、VAR2、VAR3的三個變量都存放在DSEG數(shù)據(jù)段中,如果設DSEG數(shù)據(jù)段的段首址為1355H,則這三個變量的段屬性為1355H。注意:當在指令中要對這些變量進行操作時,事先要把它們所在段的段首址存放在某一個段寄

8、存器(如DS)中。(2)偏移屬性(OFFSET)變量的偏移屬性指的是變量在邏輯段中離段起始的字節(jié)數(shù)。例如VAR1、VAR2、VAR3這三個變量的偏移量為00H、01H和02H。上述段屬性和偏移屬性就構成了變量的邏輯地址。(3)類型屬性(TYPE)變量的類型屬性指的是變量占用存儲單元的字節(jié)數(shù)。這一屬性是由數(shù)據(jù)定義偽指令DB(1字節(jié))、DW(2字節(jié))、DD(4字節(jié))、DQ(8字節(jié))、DT(10字節(jié))等來規(guī)定的。由DB定義的變量,其類型屬性為1;由DW定義的變量,其類型屬性為2;由DD定義的變量,其類型屬性為4;由DQ定義的變量,其類型屬性為8;由DT定義的變量,其類型屬性為10。所以變量VAR1、

9、VAR2、VAR3的類型屬性分別為1字節(jié)、1字節(jié)和2字節(jié)。2. 變量的使用(1)在指令語句中的使用要對某存儲單元進行存取操作,可直接引用它的變量名。例4-1 變量的應用。解:在程序中直接引用變量名,其含義是訪問該變量名所指向的內存單元。程序代碼編寫如下:DSEG SEGMENTVAR1 DB 12HVAR2 DB 20HDSEG ENDSCSEG SEGMENTASSUME CS:CSEG,DS:DSEGSTART:MOV AX,DSEGMOV DS,AX ;將數(shù)據(jù)段DSEG的段首址送入DS寄存器MOV BL,VAR1 ;將VAR1的內容12H送入BL寄存器MOV DL,VAR2 ;將VAR1

10、的內容20H送入DL寄存器ADD BL,DL MOV AH,4CHINT 21H ;返回DOSCSEG ENDSEND START(2)在偽指令中的應用變量被定義后,還可以被另外的變量進行引用。引用形式有兩種: 變量B DW 變量A 變量B DD 變量A說明:對于第一種引用形式,變量B被定義為字變量,并且在語句中引用了變量A,所以變量B所指向的字單元內容就為變量A的偏移量;對于第二種引用形式,變量B被定義為雙字變量,并且在語句中引用了變量A,所以變量B所指向的雙字單元內容就為變量A的偏移量和段首址,其中低地址字單元存放了變量A的偏移量,高地址字單元存放了變量A的段首址。注意:當變量引用變量時,

11、應該使用DW和DD偽指令進行定義,而不允許使用DB、DQ、DT等偽指令。例4-2 變量引用變量。解:假設變量VAR1被定義成字節(jié)型變量,再定義變量VAR2為字變量,并引用變量VAR1,然后再定義變量VAR3為字變量,并引用變量VAR2,最后再定義變量VAR4為雙字變量,并引用變量VAR1。那么VAR2、VAR3、VAR4這些變量的值究竟為多少。程序代碼編寫如下:DSEG SEGMENT VAR1 DB 12H VAR2 DW VAR1 VAR3 DW VAR2 VAR4 DD VAR1DSEG ENDSCSEG SEGMENT ASSUME CS:CSEG,DS:DSEG START: MOV

12、 AX,DSEG MOV DS,AX MOV BX,VAR2 MOV CX,VAR3 MOV DX,WORD PTR VAR4 MOV SI,WORD PTR VAR4+2 MOV AH,4CH INT 21HCSEG ENDS分析以上程序可知,BX、CX、DX、SI四個寄存器的內容分別對應VAR2、VAR3、VAR4的低字單元以及VAR4的高字單元。如果設例題4-2中DSEG段的段首址為013DH,則BX=0000、CX=0001H、DX=0000H、SI=013DH。4.2.3 標號標號是一條指令的目標代碼符號地址。它常作為轉移指令的操作數(shù)。例4-3 標號的使用。··&

13、#183;AGAIN:·········LOOP AGAIN···JNE EXIT···EXIT: ···例題4-3中,在指令中出現(xiàn)的標號(LOOP AGAIN指令和JMP EXIT指令)代表的是轉移地址,在匯編后,指令中出現(xiàn)的標號會被目標轉移地址所代替。而語句中開始的標號(AGAIN:和EXIT:)是為了方便定位而出現(xiàn)的,在匯編后該標號不會出現(xiàn)。與變量類似,每個標號具有如下三個屬性:(1)段屬性(SEG)表示該條指

14、令的目標代碼在哪個邏輯段中。(2)偏移屬性(OFFSET)標號的偏移屬性表示這條指令目標代碼的首字節(jié)在段內離段起始點的字節(jié)數(shù)。同變量屬性一樣,上述標號的段屬性和偏移屬性就構成了轉移目標指令的邏輯地址。(3)類型屬性(DISTANCE)標號的類型屬性表示該標號是段內轉移還是段間轉移。標號的類型屬性分為兩種:近(NEAR)表示通過本標號只能轉移到本標號所在段(即段內轉移)。遠(FAR)表示通過本標號可轉移至其他段(段間轉移)。注意:標號如果未作說明,則默認類型屬性為NEAR。4.3 數(shù)據(jù)定義偽指令常用的數(shù)據(jù)定義偽指令有以下幾種:(1)DB 偽指令:用于定義字節(jié)(單字節(jié)),其后的每個操作數(shù)都占一個字

15、節(jié)。(2)DW偽指令:用于定義字(雙字節(jié)),其后的每個操作數(shù)都占一個字。(3)DD偽指令:用于定義雙字(四字節(jié)),其后的每個操作數(shù)都占兩個字。(4)DQ偽指令:用于定義四個字(八字節(jié)),其后的每個操作數(shù)都占四個字。(5)DT偽指令:用于定義五個字(十字節(jié)),其后的每個操作數(shù)都占五個字。這些偽指令可以把其后跟著的數(shù)據(jù)存入指定的存儲單元。這些偽指令還可以先劃定出一片內容為空的存儲區(qū)域,而不需要確定這些存儲區(qū)域的內容,也就是通常所說的保留空間。4.3.1 常用的數(shù)據(jù)定義偽指令1. DB 偽指令DB偽指令初始化一個單字節(jié)存儲單元。語句格式:<變量名> DB 數(shù)據(jù)1,數(shù)據(jù)2,數(shù)據(jù)3,數(shù)據(jù)n功

16、能:定義字節(jié)數(shù)據(jù)或字符串。說明:該偽指令為每個數(shù)據(jù)項都分配了一個字節(jié)單元,所以在數(shù)據(jù)列表中給出的數(shù)據(jù)項必須小于等于8位二進制數(shù)據(jù)。對于DB語句中出現(xiàn)的字符串,每個字符均占據(jù)一個字節(jié)單元。變量名可有可無,如果有則該變量名指向數(shù)據(jù)1。數(shù)據(jù)列表可以由多個數(shù)據(jù)項組成,分別為數(shù)據(jù)1、數(shù)據(jù)2等,它們均被存儲在內存中,作為初始化值。如果數(shù)據(jù)列表中出現(xiàn)“?”,那么對應的存儲單元內容未定義,該單元也就是保留單元。數(shù)據(jù)列表中有多個數(shù)據(jù)時,必須使用逗號作為分隔符,但最后一個數(shù)據(jù)項不需要添加任何結束符。例如:VAR1 DB 12H,34H,56H,78H,“A”VAR2 DB “HELLO” 變量VAR1開始依次定義

17、5個字節(jié)數(shù)據(jù),然后再依次定義VAR2變量的5個字符數(shù)據(jù)。其存儲在內存中的形式如圖4-1所示。圖4-1 DB定義數(shù)據(jù)示意圖2. DW 偽指令DW偽指令初始化一個字存儲單元。該偽指令還常用于定義指針類型數(shù)據(jù)(偏移量)。語句格式:<變量名> DW 數(shù)據(jù)1,數(shù)據(jù)2,數(shù)據(jù)3,數(shù)據(jù)n功能:定義字數(shù)據(jù)。說明:該偽指令語句格式類似于DB偽指令。但是該偽指令為每個數(shù)據(jù)項都分配了一個字單元,所以在數(shù)據(jù)列表中給出的數(shù)據(jù)項必須小于等于16位二進制數(shù)據(jù)。另外,還必須遵守高高低低存儲原則。例如:VAR1 DW 1234H,0ABCDH,?VAR2 DW “AB”,“CD”從變量VAR1開始,依次定義了2個字數(shù)

18、據(jù)1234H和0ABCDH,接著又定義了一個字數(shù)據(jù)“?”,以上三個數(shù)據(jù)占據(jù)了6個字節(jié)。然后再定義變量VAR2,VAR2變量初始化兩個字數(shù)據(jù)“AB”(4142H)和“CD”(4344H)。其存儲形式如圖4-2所示。圖4-2 DW定義數(shù)據(jù)示意圖3. DD 偽指令DD偽指令定義一個雙字存儲單元。采用DD偽指令一般用于存儲較大的整數(shù),同時還可存放32位地址指針(段地址和偏移量)。語句格式:<變量名> DD 數(shù)據(jù)1,數(shù)據(jù)2,數(shù)據(jù)3,數(shù)據(jù)n功能:定義雙字數(shù)據(jù)。說明:該偽指令定義了4個字節(jié),一般定義較大的整數(shù)及32位指針。例如:VAR1 DD 12345678HVAR2 DD 10203040H

19、從變量VAR1開始,定義了1個雙字數(shù)據(jù)12345678H,該數(shù)據(jù)占據(jù)了4個字節(jié)。然后再定義變量VAR2數(shù)據(jù)為10203040H。其存儲形式如圖4-3所示。圖4-3 DD定義數(shù)據(jù)示意圖注意:在使用DD定義數(shù)據(jù)中,如果數(shù)據(jù)是以字符形式出現(xiàn)的,必須注意字符個數(shù)最多為2個,否則出錯。例如MESS DD “ABCD”偽指令定義語句是錯誤語句。4. DQ 偽指令DQ偽指令定義四個字存儲單元。語句格式:<變量名> DQ 數(shù)據(jù)1,數(shù)據(jù)2,數(shù)據(jù)3,數(shù)據(jù)n功能:定義4字數(shù)據(jù)。說明:該偽指令定義了4個字存儲單元。例如:VAR1 DQ 12345678HVAR2 DQ “AB”從變量VAR1開始,定義了1

20、個4字數(shù)據(jù)12345678H,該數(shù)據(jù)占據(jù)了8個字節(jié)。然后再定義變量VAR2的字符“AB”。其存儲形式如圖4-4所示。圖4-4 DQ定義數(shù)據(jù)示意圖5. DT偽指令DT偽指令定義五個字的存儲單元(10個字節(jié))。采用DT偽指令一般用于存儲10個字節(jié)長的BCD碼。語句格式如下:<變量名> DT 數(shù)據(jù)1,數(shù)據(jù)2,數(shù)據(jù)3,.數(shù)據(jù)n功能:定義5字數(shù)據(jù)。說明:該偽指令定義了10個字節(jié),一般用于存放十進制BCD碼。例如:VAR1 DT 97H定義了一個變量VAR1,該變量定義了數(shù)據(jù)97H,該數(shù)據(jù)占據(jù)了10個字節(jié)。其存儲形式如圖4-5所示。圖4-5 DT定義數(shù)據(jù)示意圖小結:在使用DW、DD、DQ和DT

21、定義字符串數(shù)據(jù)時,最多只能定義2個字符,否則匯編過程會出錯。如VAR1 DW “ABC”該偽指令語句是錯誤的。所以用戶需要定義多個(大于2個字符)字符數(shù)據(jù)時,需要使用DB偽指令進行定義。4.3.2 復制操作符DUP在以上5種數(shù)據(jù)定義偽指令中的數(shù)據(jù)項中,還可以使用復制操作符復制操作數(shù)。語句格式:<表達式> DUP (數(shù)據(jù)1,數(shù)據(jù)2,數(shù)據(jù)3,數(shù)據(jù)n)功能:重復定義DUP后面給出的數(shù)據(jù)列表,重復次數(shù)由表達式的值決定。說明:復制操作符可以重復復制數(shù)據(jù)表中給出的數(shù)據(jù),但是從整體上看它還是屬于數(shù)據(jù)定義偽指令語句中一個單獨的數(shù)據(jù)項。表達式的值應該是一個正整數(shù),用于指定括號中的數(shù)據(jù)項重復次數(shù)。DU

22、P可以進行嵌套,即數(shù)據(jù)項中還可以出現(xiàn)符合規(guī)定的復制操作符DUP。例如:VAR1 DB 2AH, 3 DUP (“A”)VAR2 DB 12H, 2 DUP (1AH,2BH,3 DUP (4CH),5DH從變量VAR1開始,定義了2A這個字節(jié)數(shù)據(jù),然后再定義了3個字符數(shù)據(jù)A(41H)。這些數(shù)據(jù)占據(jù)了4個字節(jié)。然后再定義變量VAR2后面的字節(jié)數(shù)據(jù)12H,接著連續(xù)定義2次1AH、2BH和3個4CH數(shù)據(jù),最后定義了5這個數(shù)據(jù)。其存儲形式如圖4-6所示。圖4-6 DUP重復定義數(shù)據(jù)示意圖4.3.3變量的類型屬性問題這里,我們必須再進一步說明變量類型屬性問題。變量的類型屬性(TYPE)是指變量所代表的數(shù)

23、據(jù)占用存儲單元(以字節(jié)為單位)的多少。所以數(shù)據(jù)定義偽指令DB所定義變量的類型屬性為1字節(jié),DW為2字節(jié),DD為4字節(jié),DQ為8字節(jié),而DT為10字節(jié)。我們可以使用PTR屬性操作符臨時改變變量的類型屬性,它優(yōu)先于隱含的類型屬性。語句格式:<類型> PTR <變量>說明:類型可以是BYTE或WORD,這樣就可以改變相應變量的類型屬性了。例4-4 設VAR1為字變量,內容為1234H,請編寫一個程序將VAR1的高字節(jié)送入DL寄存器,低字節(jié)送入CL寄存器。解:因為VAR1是字變量,所以在沒有進行轉換類型之前只能對該變量進行字操作。但是我們可以使用PTR屬性操作符暫時性改變VAR

24、1的類型屬性,使其能夠進行字節(jié)操作。程序代碼編寫如下:DSEG SEGMENTVAR1 DW 1234HDSEG ENDSCSEG SEGMENTASSUME CS:CSEG,DS:DSEG START: MOV AX,DSEG MOV DS,AX MOV DL,BYTE PTR VAR1+1 ;VAR1變量高字節(jié)單元內容送DL寄存器 MOV CL,BYTE PTR VAR1 ;VAR1變量低字節(jié)單元內容送CL寄存器 MOV AH,4CH INT 21H ;返回DOS CSEG ENDS END START該程序的MOV DL,BYTE PTR VAR1+1和MOV CL,BYTE PTR V

25、AR1指令將VAR1暫時性改變?yōu)樽止?jié)變量,將VAR1的高字節(jié)的內容送入DL寄存器中,而低字節(jié)內容送入了CL寄存器。當這兩條指令執(zhí)行完畢后,變量VAR1仍然為字變量。程序經保存、匯編、連接和DEBUG后,使用U命令查看反匯編后,再輸入G 000F命令執(zhí)行程序。結果如圖4-7所示。圖4-7 調試結果由圖4-7可知, VAR1+1代表了0001H偏移量,VAR1代表了0000H偏移量。4.4符號定義偽指令4.4.1 符號定義偽指令(EQU)在設計匯編語言程序時,有時多次出現(xiàn)同一個數(shù)值或表達式。為方便起見,可通過符號定義偽指令給它賦予一個符號名,以后就可以用這個符號名代替這個數(shù)值或表達式。語句格式:符

26、號名 EQU 表達式功能:用符號名代表該表達式的值。說明:EQU偽指令可以將符號名等價于一個常量或一個能求出常數(shù)值的表達式。還可以在EQU語句中引用一個已經定義的符號名,甚至可以定義為一條可執(zhí)行的命令。但是EQU偽指令不允許對同一個符號名重復定義。例4-5 請分析以下程序,掌握EQU的用法。CSEG SEGMENT ASSUME CS:CSEG START: ACC EQU AX ;符號ACC等價于AX寄存器 MOV ACC,DSEG ;等價于MOV AX,DSEG MOV DS,ACC ;等價于MOV DS,AX MOV AH,4CH INT 21H ;返回DOSCSEG ENDSEND S

27、TART由例4-5可知,EQU語句可在代碼段中出現(xiàn),并可以使用EQU語句定義關鍵字或指令助記符。例4-6請分析以下程序,掌握EQU的用法。RT1 EQU 12H ;符號RT1等價于12HRT2 EQU RT1*2 ;符號RT2等價于12H*2DSEG SEGMENT VAR1 DW 1234HDSEG ENDSCSEG SEGMENT ASSUME CS:CSEG,DS:DSEG START: MOV AX,DSEG MOV DS,AX MOV BX,RT1 ;BX12H MOV CX,RT2 ;CX24H MOV AH,4CH INT 21H ;返回DOSCSEG ENDSEND START

28、由例4-6可知,等價語句還可以放在數(shù)據(jù)段和代碼段之外,符號還可以等價于某個表達式的值。例4-7請分析以下程序,掌握EQU的用法。DSEG SEGMENT VAR1 DW 1234H VARB1 EQU BYTE PTR VAR1+1 ;VARB1指向VAR1的高字節(jié) VARB2 EQU BYTE PTR VAR1 ;VARB2指向VAR2的低字節(jié)DSEG ENDSCSEG SEGMENT ASSUME CS:CSEG,DS:DSEG START: MOV AX,DSEG MOV DS,AX MOV DL,VARB1 ;等價于MOV DL,BYTE PTR VAR1+1 MOV CL,VARB2

29、 ;等價于MOV CL,BYTE PTR VAR1 MOV AH,4CH INT 21H ;返回DOSCSEG ENDSEND START該程序等價于例4-4的程序代碼,由此可知,EQU還可以定義存儲器操作數(shù)符號。注意:(1)等價語句不會給符號分配存儲單元。(2)等價語句定義的符號不能與其他符號相同,也不允許重新定義。(3)如果在程序中要使用符號,必須遵循先定義后使用的規(guī)則。4.4.2 賦值偽指令(=)語句格式:符號名 = 表達式功能:將語句中的表達式的值賦予該符號。說明:賦值偽指令“=”與EQU功能類似,并且賦值偽指令“=”允許對符號名重復定義。例4-8 “=”偽指令的使用解:“=”賦值偽指

30、令可以使用不同的表達式多次對同一個符號進行賦值,但是在一個表達式中如果出現(xiàn)了另外一個符號,該符號應該已經被EQU或“=”定義了。TIGER =12AGE EQU 34TIGER =TIGER+AGE ;重復定義TIGER符號CSEG SEGMENT ASSUME CS:CSEG START: MOV BX,TIGER MOV AH,4CH INT 21HCSEG ENDSEND START該程序執(zhí)行后,BX=2EH,即46D。4.4.3 定義符號名語句語句格式:符號名 LABEL 類型功能:定義該符號名具有LABEL后面所給出的類型,并且使該符號名的段屬性和偏移屬性與下一個緊接著的存儲單元的段

31、屬性和偏移屬性相同。其中類型可以為變量類型BYTE、WORD、DWORD或標號類型FAR、NEAR。例4-9 分析以下程序,掌握LABEL偽指令語句用法。DSEG SEGMENT BYTE1 LABEL BYTE ;定義BYTE1符號名為字節(jié)類型 VAR1 DW 1234H ;定義了一個字變量 DSEG ENDSCSEG SEGMENT ASSUME CS:CSEG,DS:DSEG START: MOV AX,DSEG MOV DS,AX MOV BH,BYTE1 ;將BYTE1的單元內容送BH MOV BL,BYTE1+1 ;將BYTE1+1單元的內容送BL MOV AH,4CH INT 2

32、1H ;返回DOS CSEG ENDSEND START該程序定義的VAR1變量其屬于字類型,所以如果使用指令訪問該變量時,只能允許字訪問。但是該程序中在定義VAR1變量之前使用了BYTE1 LABEL BYTE語句,使BYTE1該符號為字節(jié)類型,并且與變量VAR1具有相同的段首址和偏移量,所以MOV BH,BYTE1指令其實是訪問了VAR1的低字節(jié)單元,即將VAR1的低字節(jié)內容34H送入了BH寄存器。同樣,MOV BL,BYTE1+1指令訪問了VAR1的高字節(jié)單元,將12H送入了BL寄存器,所以該程序執(zhí)行完畢后,BX寄存器內容為3412H。由以上分析可知,LABEL偽指令其實質是允許用戶對某

33、存儲單元指定不同的類型,從而使程序在訪問這些存儲單元時,擁有更靈活的自由權限。例4-10 設數(shù)據(jù)段有一個字數(shù)據(jù)1234H,將該數(shù)據(jù)的整體內容與低字節(jié)相加后,將16位和存儲到該字單元中。解:該題目要求對該字數(shù)據(jù)既要做字操作,又要做字節(jié)操作。所以使用LABEL偽指令對該字單元指定另外一種類型,即字節(jié)類型,以方便我們取字節(jié)數(shù)據(jù)。程序編寫如下:DSEG SEGMENT BYTE1 LABEL BYTE ;定義字節(jié)類型 VAR1 DW 1234H ;定義字變量DSEG ENDSCSEG SEGMENT ASSUME CS:CSEG,DS:DSEG START: MOV AX,DSEG MOV DS,AX

34、 MOV AX,VAR1 ;取字數(shù)據(jù) MOV BL,BYTE1 ;取字節(jié)數(shù)據(jù)34H ADD AL,BL ;求低8位和 ADC AH,00H ;求高8位和 MOV VAR1,AX ;將16位和存回VAR1字單元 MOV AH,4CH INT 21H ;返回DOSCSEG ENDSEND START由以上程序我們可以清晰的發(fā)現(xiàn),對于VAR1的這個字存儲單元,在程序中我們既可做字操作,如MOV AX,VAR1,又可做字節(jié)操作,如MOV BL,BYTE1。同樣道理,對于標號我們也可以指定某標號具有2種類型:FAR和NEAR。使該標號既具有遠屬性,又具有近屬性,方便程序的轉移。4.4.4 THIS操作符

35、 語句格式:THIS 類型功能:把運算符后面指定的類型屬性賦給當前的存儲單元。而該單元的段和偏移量屬性不變。其中,THIS語句中的類型可以是BYTE、WORD、DWORD、NEAR或FAR。THIS操作符與LABEL操作符功能類似,但THIS操作符一般使用在符號定義EQU語句中,指定某個符號名具有某種類型。例如:BYTE1 EQU THIS BYTEVAR1 DW 1234HBYTE1該符號代表的就是變量VAR1的低字節(jié)。如果在程序中出現(xiàn)“MOV AL,BYTE1”,等價于“MOV AL,BYTE PTR VAR1”4.5段定義偽指令8086/8088 CPU訪問存儲器時,是把存儲器分成若干段

36、,用四個段寄存器對各段進行訪問。因此,我們在編制任一源程序時,亦必須按段來構造程序。一個程序通常按用途劃分成幾個段,如存放數(shù)據(jù)的數(shù)據(jù)段,作堆棧使用的堆棧段,存放主程序的代碼段以及存放附加數(shù)據(jù)的附加段等,但是一個源程序至少必須定義一個代碼段。由于每個段的物理空間都必須小于或等于64KB,所以上述用途的各段可以分別是一個或幾個。4.5.1 段定義偽指令(SEGMENT和ENDS)當程序中需要設置一個段時,必須使用段定義偽指令。一個完整的段定義語句格式如下:段名 SEGMENT 定位類型組合類型類別名····段名 ENDS每個段都以SEGMENT偽指令開始,以

37、ENDS偽指令結束。1. 段名由用戶自己編寫,通常使用與本段用途相關的名字。例如數(shù)據(jù)段名一般使用DSEG1、DSEG2;堆棧段使用STACK1、STACK2;代碼段使用CSEG;附加段使用EXTRA1、EXTRA2等。應該注意的是,每個段的開始與結尾用的段名應該一致。在同一模塊中,如某個段名和已有段名相同,則表示是已有段的繼續(xù),與同名段屬于同一個段,此時要求SEGMENT之后的所有可選項的內容與已有同名段的取值相同。例4-11 同名段的組合。解:在同一個匯編語言源程序中,可以具有多個同名的數(shù)據(jù)段、代碼段、堆棧段或附加段。對于同名的代碼段,前面的代碼段的最末尾只允許采用ENDS作為結束符,而最后

38、一個代碼段在使用了ENDS后,還必須使用“END 標號”作為結束符。其他段(數(shù)據(jù)段、附加段和堆棧段)無此要求。程序代碼如下:DSEG SEGMENT VAR1 DW 1234HDSEG ENDS ;第一個數(shù)據(jù)段結束DSEG SEGMENT VAR2 DW 5678HDSEG ENDS ;第二個同名數(shù)據(jù)段結束CSEG SEGMENT ASSUME CS:CSEG,DS:DSEG START: MOV AX,DSEG MOV DS,AX MOV BX,VAR1 MOV CX,VAR2CSEG ENDS ;第一個代碼段結束 CSEG SEGMENT ADD BX,CX MOV AH,4CH INT

39、21H ;返回DOS CSEG ENDS ;第二個同名代碼段結束 END START ;整個程序結束由該程序代碼可知,整個程序由2個同名的數(shù)據(jù)段和2個同名的代碼段組成,其中最后一個代碼段還附加了END START偽指令,需要強調的是,在第一個代碼段結束的地方請不要使用返回DOS指令,以及在段的結尾的地方不要使用“END 標號”偽指令。該程序經保存、匯編、連接以及DEBUG后,使用U命令查看該程序代碼。如圖4-8所示。圖4-8 同名代碼段組合示意圖由圖4-8可知,兩個同名的代碼段合并為一個代碼段了。2. 定位類型定位類型可以對每個段落在內存中的起始位置進行定位。段在內存中的定位類型主要有五種類型

40、供用戶選擇。(1)PAGE(頁)表示本段從一個頁的開始位置進行存儲。一頁為256個字節(jié),所以段的起始物理地址一定能被256整除。(2)PARA(節(jié))表示本段從一個節(jié)的開始位置進行存儲。一節(jié)為16個字節(jié),所以段的起始物理地址一定能被16整除。該定位類型是段定義的默認定位類型。(3)DWORD(字)表示本段從一個雙字邊界地址進行存儲。所以段的起始物理地址的一定能被4整除。 (4)WORD(字)表示本段從一個偶字節(jié)的地址進行存儲。所以段起始地址一定能被2整除。(5)BYTE(字節(jié))表示本段可以從任意一個字節(jié)開始。該定位類型可以節(jié)約存儲空間,使每個段可以連續(xù)存儲在內存中。以上五種定位類型與段的起始地址

41、關系如表4-1所示。表4-1 定位類型與段的起始地址關系定位類型功能說明可能造成浪費的字節(jié)數(shù)PAGE表示為下一頁地址255PARA表示為下一節(jié)地址15DWORD表示為下一雙字地址3WORD表示為下一字地址1BYTE表示為下一字節(jié)地址0系統(tǒng)默認的定位類型是PARA。BYTE和WORD常用于數(shù)據(jù)段的定位,而DWORD、PARA以及PAGE常用于代碼段的定位。由于規(guī)定了對段起始地址的要求,因此段和段之間可能有若干個字節(jié)會被浪費,PAGE造成的空閑較多。例4-12 PAGE定位類型與段的起始地址關系。解:對數(shù)據(jù)段和附加段定義時均添加PAGE定位類型,使這兩個段間隔1個頁,然后執(zhí)行該程序,查看數(shù)據(jù)段和附

42、加段之間的間隔距離是否為1個頁。程序代碼編寫如下:DSEG1 SEGMENT PAGE VAR1 DB 12H,34H VAR2 DB 56H,78HDSEG1 ENDSEXTRA1 SEGMENT PAGE VAR3 DB 0ABH,0CDH VAR4 DB 0EEH,0FFHEXTRA1 ENDSCSEG SEGMENT ASSUME CS:CSEG,DS:DSEG1,ES:EXTRA1 START: MOV AX,DSEG1 MOV DS,AX MOV AX,EXTRA1 MOV ES,AX MOV AH,4CH INT 21H CSEG ENDS END START保存該文件,名稱為1

43、11.ASM后,通過MASM程序匯編成111.OBJ,再通過LINK程序連接成111.EXE,再使用DEBUG 111.EXE命令中的U查看。結果如圖4-9所示。圖4-9 U命令效果圖由圖4-9可知,數(shù)據(jù)段DSEG1的段首址為13D6H,附加段EXTRA1的段首址為13E6H,但是該程序還沒有執(zhí)行,所以DS和ES寄存器的內容還不是13D6H和13E6H,所以還應輸入“G 000C”命令,將段首址裝入DS和ES。執(zhí)行完畢后,再輸入“D 13D6:0000”查看數(shù)據(jù)段DSEG1所占內存區(qū),然后再輸入“D 13E6:0000”命令查看附加段EXTRA1所占內存區(qū)。如圖4-10所示。圖4-10 PAG

44、E定位效果圖由圖4-10可知,數(shù)據(jù)段DSEG1和附加段的段首地址差為:13E60H-13D60H=0100H,即間隔256個字節(jié)(一個頁)。如果將該程序中的PAGE均改為BYTE,數(shù)據(jù)段DSEG1和附加段EXTRA1兩者之間的存儲關系如圖4-11所示。圖4-11 BYTE定位效果圖3. 組合類型組合類型用于通知連接程序LINK,如何將不同模塊之間的同名段進行連接。有六種參數(shù)供用戶選擇。(1)NONENONE的含義是什么都不提供,即用戶在段定義時,不給出任何組合類型關鍵詞,則屬于NONE類型。所以請讀者不要在SEGMENT后面加“NONE”。NONE是組合類型的默認值,表示本段與其他模塊的同名段

45、無連接關系。在裝入內存時本段有自己的物理段。例4-13 NONE組合類型舉例。解:分別在111.ASM和222.ASM文件中編輯一個相同名稱的代碼段,然后分別對這兩個文件進行匯編,再使用LINK連接程序將111.OBJ文件和222.OBJ連接成一個111.EXE可執(zhí)行文件,再使用DEBUG觀察2個文件的指令所在位置。111.ASM文件程序代碼編寫如下:CSEG SEGMENT ;SEGMENT后面什么都不給即NONE類型 ASSUME CS:CSEG START: MOV BX,1234H MOV AH,4CH INT 21HCSEG ENDSEND START222.ASM文件的程序代碼編寫

46、如下:CSEG SEGMENT ASSUME CS:CSEG START: MOV CX,5678H MOV AH,4CH INT 21HCSEG ENDSEND START輸入MASM 111.ASM和MASM 222.ASM,生成對應的111.OBJ和222.OBJ文件。輸入LINK 111.OBJ+222.OBJ命令,將這兩個模塊連接成一個111.EXE可執(zhí)行文件。如圖4-12所示。圖4-12 LINK連接多模塊輸入DEBUG 111.EXE命令,然后輸入U命令查看反匯編。如圖4-13所示。圖4-13 NONE組合示意圖由圖4-13,可以明確111.ASM文件的指令,但是沒有發(fā)現(xiàn)222.

47、ASM文件的指令。經觀察,發(fā)現(xiàn)“ADD BX+DI+5678,BH”及其后續(xù)兩條指令很像222.ASM文件的代碼。仔細分析后,覺得“ADD BX+DI+5678,BH”所對應機器碼中的“B97856”與指令“MOV CX,5678H”的機器碼相同。所以再輸入“U 13D6:0010”命令,查看222.ASM文件的指令是否從該地址開始存放。如圖4-14所示。圖4-14 模塊2反匯編示意圖從圖4-14發(fā)現(xiàn),從13D6:0010H單元開始存放的正是222.ASM的代碼,通過和圖4-13比較,程序222.ASM的代碼并沒有和111.ASM的代碼連續(xù)存放,它們之間間隔了9個字節(jié)單元。通過該例題可以清晰地

48、發(fā)現(xiàn)111.ASM的CSEG段和222.ASM的CSEG段不存在連接關系。(2)PUBLIC在滿足定位類型的前提下,本段與同名段連接在一起,形成一個新的邏輯段,公用一個段首址,所有偏移量調整為相對于新邏輯段的起始地址。例4-14 將例4-13的NONE組合類型改為PUBLIC組合類型。解:PUBLIC組合類型可以將多個不同模塊的同名段組合成一個段,但是必須注意的是PUBLIC組合類型在組合過程中,其前提條件是段首先需要滿足定位類型,再進行連接。如果該例僅僅添加PUBLIC組合類型,111.ASM文件和222.ASM文件的代碼仍然無法連接,因為這兩個CSEG段的定位類型默認為PARA(16個字節(jié)

49、),但是這兩個CSEG段的代碼無須占用16個字節(jié),所以雖然在段定義中給出了PUBLIC,兩個模塊之間仍然無法實現(xiàn)連接,這一點請讀者千萬注意。為了解決這個問題,通常是給出BYTE定位類型,以使段與段之間緊密連接。其他調試過程同例4-13。111.ASM文件程序代碼編寫如下:CSEG SEGMENT PUBLIC ;第一個模塊無須給出定位類型 ASSUME CS:CSEG START: MOV BX,1234H MOV AH,4CH INT 21HCSEG ENDSEND START222.ASM文件的程序代碼編寫如下:CSEG SEGMENT ASSUME CS:CSEG BYTE PUBLIC

50、 ;第二個模塊必須給出定位類型 START: MOV CX,5678H MOV AH,4CH INT 21HCSEG ENDSEND START余下調試步驟同例4-13,此處不再一一給出。組合結果如圖4-15所示。圖4-15 PUBLIC組合示意圖由圖4-15可知,采用PUBLIC組合不同模塊之間的同名段時,被組合段的定位類型應該采用BYTE。(3)COMMON產生一個覆蓋段。在兩個模塊連接時,把本段與其他亦用COMMON說明的同名段設置成相同的起始地址,共享相同的存儲區(qū)。共享存儲區(qū)的長度由同名段中最大的段確定。例4-15將例4-14的PUBLIC組合類型改為COMMON組合類型。解:COMM

51、ON組合類型將不同模塊之間的同名段采用覆蓋形式組合成一個段,而不會考慮定位類型。為了展示覆蓋效果,對111.ASM文件程序代碼改寫如下:CSEG SEGMENT COMMON ASSUME CS:CSEG START: MOV BX,1234H NOP NOP NOP NOP NOP NOP NOP NOP MOV AH,4CH INT 21HCSEG ENDSEND START為了展示COMMON組合類型無須考慮定位類型,222.ASM文件的程序代碼改寫如下:CSEG SEGMENT ASSUME CS:CSEG PAGE COMMON START: MOV CX,5678H MOV AH,

52、4CH INT 21HCSEG ENDSEND START輸入MASM 111.ASM和MASM 222.ASM,生成對應的111.OBJ和222.OBJ文件。輸入LINK 111.OBJ+222.OBJ命令,將這兩個模塊連接成一個111.EXE可執(zhí)行文件。輸入DEBUG 111.EXE命令,然后輸入U命令查看反匯編。如圖4-16所示。圖4-16 COMMN組合示意圖由圖4-16可知,采用COMMON組合類型將產生覆蓋效果,并且無須考慮定位類型對COMMON的影響。這一點和PUBLIC不同。(4)STACK組合類型STACK表示該段為堆棧段,組合情況同PUBLIC。(5)AT 表達式表示當前段

53、應按照絕對地址定位,該段的段首址即為表達式的值。AT 表達式一般不用于代碼段和初始化數(shù)據(jù)的數(shù)據(jù)段或附加段,但是可以用于緩沖區(qū)的定義段,例4-16 AT表達式在緩沖區(qū)的應用。解:定義一個緩沖區(qū),該緩沖區(qū)段首址必須為2000H。程序代碼編寫如下:DSEG SEGMENT AT 2000H BUFFER DB 200 DUP(?)DSEG ENDSCSEG SEGMENT ASSUME CS:CSEG,DS:DSEG START: MOV AX,DSEG MOV DS,AX MOV AH,4CH INT 21HCSEG ENDSEND START保存該文件,名稱為111.ASM后,通過MASM程序匯

54、編成111.OBJ,再通過LINK程序連接成111.EXE,再使用DEBUG 111.EXE命令中的U查看后,觀測到該程序結束地址為0007H,再輸入G 0007執(zhí)行該程序,結果如圖4-17所示。圖4-17 AT表達式示意圖由圖4-17可知,該緩沖區(qū)段首址被設置為2000H。注意:AT 表達式不允許用于代碼段或已經具有數(shù)據(jù)的段,否則LINK連接程序將無法完成連接。(6)MEMORYMEMORY組合類型表示本段在存儲器中應定位在所有其他段的最高地址。如有多個MEMORY,則只對第一個遇到的有MEMORY的段進行處理,其他的同名段均按PUBLIC說明處理。組合類型與相應同名段組合方法如表4-2所示。表4-2 組合類型及相應同名段組

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論