| 匯編語言的指令格式,目前有兩種不同的標(biāo)準(zhǔn):Windows下的匯編語言基本上都遵循Intel風(fēng)格的語法,比如:MASM、NASM;而Unix/Linux下的匯編語言基本上都遵循AT&T風(fēng)格的語法;[名稱[:]] 指令碼 [第一操作數(shù)][,第二操作數(shù)] ;注釋
 匯編語言的指令碼的操作數(shù)的個(gè)數(shù)可以是0、1、2個(gè);當(dāng)操作數(shù)的個(gè)數(shù)為2的時(shí)候,語句還有兩種不同的格式:
 Windows下Intel風(fēng)格的匯編語言語句格式為:
 [名稱[:]] 指令碼 目的操作數(shù)DST,源操作數(shù)SRC ;注釋
 Unix/Linux下AT&T風(fēng)格的匯編語言語句格式為:
 [名稱[:]] 指令碼 源操作數(shù)SRC,目的操作數(shù)DST ;注釋
 例如:
 CYCLE: ADD AX,02H 
;(AX)匯編語言語句格式中的'名稱'并不是所有語句都必需的,但是,如果語句中帶有'名稱',那么,大多數(shù)情況下,'名稱'都表示的是內(nèi)存中某一存儲(chǔ)單元的地址,也就是'名稱'后面各項(xiàng)在內(nèi)存中存放的第一個(gè)存儲(chǔ)單元的地址(包括該'名稱'所在段的段地址和段內(nèi)偏移地址);比如上面的指令中,CYCLE就是該語句的名稱,CYCLE表示的就是其后面的機(jī)器指令碼在內(nèi)存中存放的第一個(gè)地址;'名稱'與指令碼之間的分隔符可以是冒號(hào)':',也可以是空格字符'
 
';當(dāng)以冒號(hào)分割時(shí),該名稱代表的是一個(gè)標(biāo)號(hào);當(dāng)以空格分割時(shí),該名稱代表的可能是標(biāo)號(hào),也可能是變量;當(dāng)指令碼有多個(gè)操作數(shù)的時(shí)候,相鄰兩個(gè)操作數(shù)之間要用逗號(hào)','分割;指令碼與操作數(shù)之間必須以空格分割;匯編語言語句的注釋必須以分號(hào)';'開頭;
 匯編語言中的常數(shù)有整數(shù)、字符串;二進(jìn)制、八進(jìn)制、十進(jìn)制、十六進(jìn)制;匯編語言采用不同的后綴區(qū)分:
 B:二進(jìn)制數(shù); O:八進(jìn)制數(shù); D:十進(jìn)制數(shù); H:十六進(jìn)制數(shù);
 當(dāng)一個(gè)數(shù)值后面沒有后綴的時(shí)候,默認(rèn)為十進(jìn)制數(shù);
 字符串常數(shù)是用一對(duì)單引號(hào)('')括起來的一串字符;算數(shù)運(yùn)算操作符: +、-、*、/、MOD,等;取模運(yùn)算MOD是取兩數(shù)相除的余數(shù);
 邏輯運(yùn)算操作符: AND(邏輯與)、OR(邏輯或)、NOT(邏輯非)、XOR(邏輯異或);
 注意:邏輯運(yùn)算符同時(shí)又可以是邏輯運(yùn)算指令的指令碼,只有當(dāng)它們出現(xiàn)在指令的操作數(shù)部分時(shí),才是操作符;例如:
 ADD AL,0CH ADD 0FH ;第一個(gè)ADD是指令碼,第二個(gè)ADD是操作符;
 關(guān)系運(yùn)算操作符: EQ(相等)、NE(不等)、LT(小于)、GT(大于)、LE(小于等于)、GE(大于等于);
 匯編語言中的表達(dá)式不能單獨(dú)構(gòu)成語句,只能是語句的組成部分;
 注意:語句中表達(dá)式的求值不是在語句執(zhí)行時(shí)完成的,而是在對(duì)源程序進(jìn)行匯編鏈接時(shí)完成的.所以,語句中各表達(dá)式的值必須在匯編或鏈接時(shí)就是確定的,也就是說,表達(dá)式中各標(biāo)識(shí)符的值在匯編或鏈接時(shí)就應(yīng)該是確定的;
 標(biāo)號(hào)是由標(biāo)識(shí)符表示的指令的名稱,用于指示對(duì)應(yīng)指令的位置(地址);
 標(biāo)號(hào)具有三個(gè)屬性:段地址、偏移地址和類型;
 標(biāo)號(hào)的段地址和偏移地址屬性是指該標(biāo)號(hào)所對(duì)應(yīng)的指令所在段的段地址和段內(nèi)偏移地址;
 標(biāo)號(hào)的類型有兩種:NEAR和FAR;標(biāo)號(hào)定義成NEAR類型,表示該標(biāo)號(hào)在段內(nèi)使用,而定義成FAR類型則表示該標(biāo)號(hào)可以在段間使用;
 標(biāo)號(hào)的定義:在指令碼前面加上標(biāo)識(shí)符和冒號(hào)':';
 這條語句里面,START就是我們定義的標(biāo)號(hào),它代表指令PUSH的地址,所以,標(biāo)號(hào)可以作為程序轉(zhuǎn)移指令的操作數(shù)(即:要轉(zhuǎn)向的地址);標(biāo)號(hào)還可以采用偽指令來定義;例如:用LABEL偽指令和過程定義偽指令來定義;
 與高級(jí)語言一樣,并不是所有的操作數(shù)都是常數(shù),匯編語言也有自己的變量,變量的值在程序運(yùn)行期間是可以被改變的;
 A.定義變量:匯編語言中,變量的定義是通過偽指令來完成的;定義變量的偽指令格式如下:
 變量名 DB 表達(dá)式 ;定義字節(jié)變量,又稱單字節(jié)變量(1個(gè)連續(xù)字節(jié)),DB-->BYTE變量名 DW 表達(dá)式 ;定義字變量,又稱雙字節(jié)變量(2個(gè)連續(xù)字節(jié)),DW-->WORD變量名 DD 表達(dá)式 ;定義雙字變量,又稱四字節(jié)變量(4個(gè)連續(xù)字節(jié)),DD-->DWORD變量名 DF 表達(dá)式 ;定義六字節(jié)變量,又稱六字節(jié)變量(6個(gè)連續(xù)字節(jié)),DF-->FWORD變量名 DQ 表達(dá)式 ;定義長(zhǎng)字變量,又稱八字節(jié)變量(8個(gè)連續(xù)字節(jié)),DQ-->QWORD變量名 DT 表達(dá)式 ;定義十字節(jié)變量(10個(gè)連續(xù)字節(jié)),DT-->TBYTE;
 其中,變量名是一個(gè)合法的標(biāo)識(shí)符,變量名后面不能加冒號(hào)':',只能用空格;變量名不是必要的,可有可無;變量的類型由關(guān)鍵字DB、DW、DD、DQ、DT來定義;
 變量定義語句中的'表達(dá)式'是用于對(duì)變量進(jìn)行初始化的,可有一下幾種情況:
 (1).一個(gè)或多個(gè)常數(shù)或表達(dá)式;當(dāng)為多個(gè)常數(shù)或表達(dá)式時(shí),期間要用逗號(hào)隔開;如DATA1--DATA4;
 對(duì)于字節(jié)型(DB)變量,每個(gè)變量的大小為1個(gè)字節(jié),每個(gè)變量的值不能超過1個(gè)字符,每個(gè)字節(jié)內(nèi)存入一個(gè)字符的ASCII碼值,整個(gè)字符串可以在同一對(duì)單引號(hào)內(nèi)給出,這相當(dāng)于是定義了一個(gè)字符數(shù)組,如DATA5;
 對(duì)于字類型(DW)變量,每個(gè)變量的大小為2個(gè)字節(jié),每個(gè)變量的值不能超過2個(gè)字符,若為2個(gè)字符時(shí),同樣遵循高位存入高字節(jié),低位存入低字節(jié)的規(guī)則;若為1個(gè)字符,則該字符的ASCII碼值存入到低字節(jié),高字節(jié)為00,如DATA6;
 對(duì)于雙字類型(DD)變量,每個(gè)變量的大小為4個(gè)字節(jié),每個(gè)變量的值不能超過2個(gè)字符,若為2個(gè)字符,同樣遵循高位存入高字節(jié),低位存入低字節(jié)的規(guī)則;但是2個(gè)字符的值被存入到雙字變量的最低2個(gè)字節(jié)中,1個(gè)字符的值被存入到雙字變量的最低1個(gè)字節(jié)中;
 對(duì)于長(zhǎng)字類型(DQ)變量,每個(gè)變量的大小為8個(gè)字節(jié),每個(gè)變量的值不能超過2個(gè)字符,若為2個(gè)字符,同樣遵循高位存入高字節(jié),低位存入低字節(jié)的規(guī)則;但是2個(gè)字符的值被存入到長(zhǎng)字變量的最低2個(gè)字節(jié)中,1個(gè)字符的值被存入到長(zhǎng)字變量的最低1個(gè)字節(jié)中;
 (3).一個(gè)問號(hào)'?',表示該變量的值不確定,即:該變量所表示的內(nèi)存單元中的內(nèi)容是不確定的,或者說是,當(dāng)表達(dá)式為問號(hào)時(shí),變量所對(duì)應(yīng)的內(nèi)存區(qū)中并沒有存入新的值,而只是預(yù)留出了相應(yīng)的存儲(chǔ)空間;如DATA7、DATA8
 (4).重復(fù)方式;此時(shí)的格式為: 重復(fù)次數(shù) DUP(表達(dá)式);重復(fù)方式指出表達(dá)式的值可以重復(fù)地存儲(chǔ)到變量對(duì)應(yīng)的內(nèi)存區(qū)中,重復(fù)的次數(shù)由偽指令給出,相當(dāng)于定義數(shù)組;如DATA9、DATA10
 DATA2 DW 0204H,1000H ;2字節(jié)變量DATA3 DB (-1*3),(15/3) ;1字節(jié)變量DATA4 DD 123456H ;4字節(jié)變量DATA5 DB '0123' ;字符串變量,相當(dāng)于一個(gè)字符數(shù)組DATA6 DW 'AB','C','D' ;字符串變量,相當(dāng)于一個(gè)字符串?dāng)?shù)組;DATA7 DB ? ;1字節(jié)變量,未初始化DATA8 DD ? ;4字節(jié)變量,未初始化DATA9 DB 5 DUP(0) ;1字節(jié)變量,用5個(gè)0初始化,相當(dāng)于是一個(gè)具有5個(gè)DB型元素的數(shù)組DATA10 DW 3 DUP(?) ;2字節(jié)變量,未初始化,相當(dāng)于是一個(gè)具有3個(gè)DW型元素的數(shù)組變量定義語句中偽指令的功能是在變量名所對(duì)應(yīng)的地址開始的內(nèi)存區(qū)依次存入表達(dá)式中的各項(xiàng)值,表達(dá)式中的每項(xiàng)值所占用內(nèi)存字節(jié)數(shù)與變量的類型對(duì)應(yīng);總結(jié):一個(gè)變量的變量名實(shí)際上就代表了該變量所對(duì)應(yīng)的內(nèi)存區(qū)在內(nèi)存段中的有效地址(偏移地址);高地址是指地址值相對(duì)較大,低地址是指地址值相對(duì)較小,高地址與低地址是相對(duì)而言的;
 B.偏移地址(OFFSET):變量所在段內(nèi)的偏移地址;C.類型(TYPE):變量的類型定義了每個(gè)變量所占用的內(nèi)存字節(jié)數(shù),對(duì)于DB、DW、DD、DQ、DT類型定義的變量所占用的內(nèi)存字節(jié)數(shù)分別是1、2、4、8、10;通常又將DB、DW、DD類型所定義的變量分別成為BYTE類型、WORD類型、DWORD類型變量;標(biāo)識(shí)符種類 字節(jié)變量 字變量 雙字變量 近標(biāo)號(hào)NEAR 遠(yuǎn)標(biāo)號(hào)FARD.長(zhǎng)度(LENGTH):變量定義時(shí),一個(gè)變量名所定義的變量個(gè)數(shù);在含有DUP操作符的變量定義中,變量名所定義的變量個(gè)數(shù)為定義格式中的重復(fù)次數(shù);在其它各種變量定義中,每個(gè)變量名所定義的變量個(gè)數(shù)均為1個(gè);E.大小(SIZE):變量定義語句中,分配給同一個(gè)變量名的所有變量的總的字節(jié)數(shù),其值為該變量的類型與長(zhǎng)度的成績(jī);其中,段地址、偏移地址和類型屬性是變量的主屬性,而長(zhǎng)度和大小屬性是變量的輔助屬性;SEG SEG 變量名或標(biāo)號(hào) 取出變量名或標(biāo)號(hào)所在段的段地址OFFSET OFFSET 變量名或標(biāo)號(hào) 取出變量名或標(biāo)號(hào)所在段內(nèi)的偏移地址TYPE TYPE 變量名或標(biāo)號(hào) 取出變量名或標(biāo)號(hào)的類型(變量所占用的字節(jié)數(shù))LENGTH LENGTH 變量名 取出變量的長(zhǎng)度這些操作符不能單獨(dú)構(gòu)成語句,只能作為表達(dá)式的組成部分,并且表達(dá)式的求值也是在匯編過程中完成的;6.強(qiáng)制類型轉(zhuǎn)換操作符PTR
 格式:數(shù)據(jù)類型 PTR 地址表達(dá)式格式中的'數(shù)據(jù)類型'可以是BYTE、WORD、DWORD、NEAR、FAR;前三種類型是變量的類型,后兩種類型是標(biāo)號(hào)的類型;格式中的表達(dá)式可以是變量、標(biāo)號(hào)、其它地址表達(dá)式;PTR操作符的功能是用來重新定義已定義的變量或標(biāo)號(hào)的類型,其作用域只在當(dāng)前語句中; 例如:這條指令中,是把DATA1的類型轉(zhuǎn)換為BYTE類型,然后把AL中的內(nèi)容存放到DATA1的最低一個(gè)字節(jié)中;作用域只在這條MOV語句中,過了這條語句,DATA1仍然是DW類型,即:DATA1原來的類型并沒有被修改;符合數(shù)據(jù)類型,除了用DUP定義的重復(fù)數(shù)據(jù)類型之外,與C/C++語言一樣,匯編語言中
 也有結(jié)構(gòu)體類型、聯(lián)合類型、記錄類型;結(jié)構(gòu)類型名 STRUC [對(duì)齊類型Alignment][,NONUNIQUE]說明:結(jié)構(gòu)體中的字段名可有可無;若有字段名,則字段名必須唯一,每個(gè)字段可獨(dú)立存取;若沒有字段名,則通過偏移量來存取;對(duì)齊方式Alignment:定義每個(gè)字段的字節(jié)對(duì)齊邊界,對(duì)齊值有1、2、4、8、16字節(jié)對(duì)齊,值必須是2的冪次方;對(duì)齊類似于C/C++中結(jié)構(gòu)體字段的對(duì)齊;
 NONUNIQUE:要求結(jié)構(gòu)體中的字段必須用全名才能訪問;
 結(jié)構(gòu)體中的字段可以有字段名,也可以沒有字段名;有字段名的字段可直接使用該字段名來訪問,沒有字段名的字段可用使用該字段在結(jié)構(gòu)體中的偏移量來訪問;NAME DB 10 DUP(?) ;有名字段,偏移量為4字段值列表中的各個(gè)字段之間用逗號(hào)','分割,字段值的排列順序及類型應(yīng)該與該結(jié)構(gòu)定義時(shí)說明的各個(gè)字段相一致;如果結(jié)構(gòu)變量中某個(gè)字段的值使用定義結(jié)構(gòu)時(shí)說明的缺省值,那么可用逗號(hào)來表示;如果所有字段都使用定義結(jié)構(gòu)體時(shí)說明的各個(gè)字段的缺省值,則可省去字段值列表,只需保留一對(duì)尖括號(hào)''即可;
 Per1 PERSON ;所有字段都是用默認(rèn)值Per3 PERSON ;第二個(gè)字段使用默認(rèn)值;這種引用方式與高級(jí)語言中的引用方式完全一致;另外,還可以使用偏移量來訪問某個(gè)字段;
 方式2:使用字段的在結(jié)構(gòu)體中的偏移量來引用
 LEA SI,Per3 ;取變量Per3對(duì)應(yīng)內(nèi)存塊的有效地址
 MOV AX,[SI+4] ;寄存器相對(duì)尋址,4是字段NAME的偏移量
 [聯(lián)合體類型名] UNION [對(duì)齊方式Alignment][,NONUNIQUE]說明:聯(lián)合體類型中的各個(gè)字段相互覆蓋,即:同樣的存儲(chǔ)單元被多個(gè)不同類型的字段所對(duì)應(yīng),并且每個(gè)字段在聯(lián)合體類型中的偏移量都是0;聯(lián)合體類型所占用的字節(jié)數(shù)是其所有字段所占字節(jié)數(shù)的最大值,即:聯(lián)合體所占用的字節(jié)數(shù)是這個(gè)聯(lián)合體的所有字段中占用字節(jié)數(shù)最多的那個(gè)字段占用的字節(jié)數(shù);
 對(duì)齊方式Alignment:可用1、2、4、8、16個(gè)字節(jié)來指定聯(lián)合體中各個(gè)字段字節(jié)的對(duì)齊邊界,其缺省的對(duì)齊邊界是1字節(jié);還可用使用偽指令A(yù)LIGN或EVEN來重新定界,也可使用命令行選項(xiàng)/Zp來定界;
 NONUNIQUE:要求聯(lián)合體類型中的字段必須使用全名才能訪問;
 聯(lián)合體類型的變量只能使用第一個(gè)字段的數(shù)據(jù)類型來進(jìn)行初始化;例如:DATE1 DATE ;定義一個(gè)聯(lián)合體類型變量DATE1,并使用第一個(gè)字段的數(shù)據(jù)類型進(jìn)行初始化DATE2 DATE ;初始化錯(cuò)誤,只能使用第一個(gè)字段的數(shù)據(jù)類型進(jìn)行初始化;MOV DATE1.YEAR,2012 ;給聯(lián)合體類型變量字段賦值MOV AL,DATE1.MONTH ;AL=07MOV BX,DATE1.YEAR ;BX=2012MOV DATE1.MONTH,08 ;月份置為8月匯編語言中的記錄類型與高級(jí)語言中的記錄類型不同,在匯編語言中,記錄類型是為按照二進(jìn)制位存取數(shù)據(jù)提供方便的;記錄類型的說明要用到另一個(gè)關(guān)鍵字RECORD,格式如下:其中,'字段'代表: 字段名:寬度[=初始值表達(dá)式]說明:記錄名代表該記錄類型;記錄類型可以由多個(gè)字段組成,相鄰兩個(gè)字段之間用逗號(hào)隔開;記錄類型中字段的屬性包括字段名、寬度和初始值;記錄類型中,字段的'寬度'屬性表示該字段所占用的二進(jìn)制位數(shù),它必須是一個(gè)常數(shù),并且所有字段的寬度之和不能大于16(即:有字段的寬度之和大于8,則系統(tǒng)會(huì)自動(dòng)為該記錄類型分配2字節(jié)的空間,否則只分配1個(gè)字節(jié)的空間;記錄類型的最后一個(gè)字段排在所分配空間的最低位,然后對(duì)記錄中的字段依次'從右向左'分配二進(jìn)制位,左邊沒有分完的二進(jìn)制位自動(dòng)補(bǔ)0;初值表達(dá)式給出的是該字段的缺省值,如果初值超過了該字段所表示的范圍,那么,在匯編時(shí)將產(chǎn)生錯(cuò)誤提示信息,如果某字段沒有初值表達(dá)式,則其初值為0;COLOR RECORD BLINK:1,BACK:3=0,INTENSE:1=1,FORE:3該COLOR類型的二進(jìn)制位分布如下圖所示:該類型的各個(gè)字段寬度為:1、3、1、3,所以,該記錄占用8個(gè)二進(jìn)制位,系統(tǒng)為它分配1個(gè)字節(jié);FLOAT RECORD DSIGN:1,DATA:8,ESIGN:1,EXP:4該FLOAT類型的二進(jìn)制位分布如下圖所示:該類型的總寬度是14個(gè)二進(jìn)制位,所以,系統(tǒng)為它分配2個(gè)字節(jié)的空間;說明:變量名就是該記錄類型的變量名,它可缺省,則不能使用符號(hào)名來訪問該內(nèi)存單元;字段值列表是用于給各個(gè)字段賦初值,相鄰兩個(gè)字段值之間用逗號(hào)','隔開,其字段值的排列順序及大小應(yīng)該按照記錄類型定義時(shí)說明的各個(gè)字段的順序和大小來排列;如果記錄類型變量的某個(gè)字段使用默認(rèn)值,那么,可用逗號(hào)來表示,如果所有字段都是用默認(rèn)值,則可省去字段值列表,但必須保留一對(duì)尖括號(hào)'';操作符WIDTH和MASK是專用于記錄類型的操作符,利用它們可用得到記錄類型的不同屬性;WIDTH:用于返回記錄或其字段的二進(jìn)制位數(shù),即:記錄類型或記錄類型字段的寬度;書寫格式如下:
 例如:記錄類型COLOR,那么,WIDTH COLOR的值為8,WIDTH BACK的值為3,WIDTH BLINK的值為1;MASK:它返回一個(gè)8位或16位的二進(jìn)制數(shù),在該二進(jìn)制數(shù)中,被指定記錄或字段使用的對(duì)應(yīng)位的值為1,否則,其值為0;書寫格式如下:例如:記錄類型FLOAT,那么,MASK EXP的值為000FH,MASK DATA的值為1FE0H,MASK DSIGN的值為2000H;
 記錄字段:記錄字段名是一個(gè)特殊的操作符,它本身也是一個(gè)操作數(shù),其返回值是該字段移到該字段所在記錄的最低位所需要的位數(shù),即:該字段最低位在記錄中的位置;MOV CL,EXP 相當(dāng)于 MOV CL,0MOV CL,DATA 相當(dāng)于 MOV CL,5已知某一數(shù)據(jù)類型,程序員可以定義這個(gè)數(shù)據(jù)類型的別名或指針類型.表達(dá)這種定義的偽指令是TYPEDEF,其定義形式如下:新數(shù)據(jù)類型名 TYPEDEF [位距][PTR] 已知數(shù)據(jù)類型CHAR TYPEDEF BYTE ;給BYTE類型定義另外一個(gè)別名CHAR,C++中就是: typedef BYTE CHARPCHAR TYPEDEF PTR CHAR ;定義一個(gè)字符指針數(shù)據(jù)類型PCHAR,C++中就是:typedef PTR CHAR PCHAR,即:typedef char* PCHARCH1 CHAR 'ABCDEF' ;定義一個(gè)字符串常量PCH1 PCHAR CH1 ;定義一個(gè)指向字符串常量CH1的變量這個(gè)功能類似于C++語言中的typedef語句;SEG(段地址)、OFFSET(偏移量)、TYPE(數(shù)據(jù)類型)、LENGTH(變量長(zhǎng)度)、SIZE(變量容量)WIDTH(記錄/記錄字段的寬度)、MASK(記錄/記錄字段的屏蔽位),等等;其中,HIGH和LOW分別用于選取表達(dá)式計(jì)算結(jié)果的高8位和低8位,使用格式如下:9.運(yùn)算符和操作符的優(yōu)先級(jí):優(yōu)先級(jí): 高 LENGTH、SIZE、WIDTH、MASK、()、[]、.(用于結(jié)構(gòu)字段)、(用于記錄類型)↓ PTR、SEG、OFFSET、TYPE、THIS、:(用于段超越前綴)地址表達(dá)式是計(jì)算存儲(chǔ)器單元地址的表達(dá)式,它可由標(biāo)號(hào)、變量名和由方括號(hào)'[]'括起來的基址或變址寄存器組成;其計(jì)算結(jié)果表示一個(gè)存儲(chǔ)器單元的地址,而不是該存儲(chǔ)器單元中的值;注意:匯編語言中,對(duì)地址數(shù)值的運(yùn)算都是以字節(jié)為單位的,而不是以數(shù)據(jù)類型的大小為單位的;例如:則,地址表達(dá)式W1+1處的內(nèi)存單元中的數(shù)據(jù)是7812H,而不是5678H;W1+1表示W(wǎng)1為起始地址,其下一個(gè)字節(jié)單元的地址,W1+2表示從地址W1出開始,其后2個(gè)字節(jié)單元地址;在程序中,經(jīng)常會(huì)用到一些常數(shù)或數(shù)值表達(dá)式,并把它們直接寫在指令值,當(dāng)時(shí)當(dāng)需要修改的時(shí)候,就要對(duì)它們逐一進(jìn)行修改,這無疑就增加了維護(hù)程序的工作量,而且每個(gè)常量或表達(dá)式所代表的含義也容易忘記;于是,匯編語言提供了為常量或表達(dá)式定義一個(gè)符號(hào)名的方法;一旦定義了符號(hào)名,在指令中就可以直接使用它們了;這個(gè)功能就類似于C語言中使用宏定義指令#define定義常量的功能相似,也與C++中使用const關(guān)鍵字定義常量的功能相似;作用:左邊的符號(hào)名代表右邊的表達(dá)式;注意:等價(jià)語句不會(huì)給符號(hào)名分配存儲(chǔ)空間,符號(hào)名不能與其它符號(hào)名重名,即:符號(hào)名必須唯一;符號(hào)名也不能被重新定義;程序中凡是出現(xiàn)'表達(dá)式'的地方,都使用'符號(hào)名'來替換;(2).使用符號(hào)名代表常量或表達(dá)式把一個(gè)常量或表達(dá)式定義成一個(gè)具有一定含義的符號(hào)名之后,在程序中就可以用該符號(hào)名來代表該常量或表達(dá)式;例如:NUMBER EQU 100 ;給緩沖區(qū)的長(zhǎng)度取一個(gè)符號(hào)名CR EQU 13 ;給'回車'符的ASCII碼定義一個(gè)符號(hào)名LN EQU 10 ;給'換行'符的ASCII碼定義一個(gè)符號(hào)名GREETING EQU 'How are you!'(4).用符號(hào)名代表關(guān)鍵字或指令碼MOVE EQU MOV ;給指令碼MOV取另外一個(gè)符號(hào)名MOVECOUNTER EQU CX ;給寄存器CX取一個(gè)叫做'計(jì)數(shù)器'的符號(hào)名匯編語言提供了使用等號(hào)'='來定義符號(hào)常數(shù)的方法,即:可用符號(hào)名代表一個(gè)常數(shù);一般格式如下:數(shù)值表達(dá)式在匯編時(shí)應(yīng)該可以計(jì)算出值,它不能含有向前引用的符號(hào)名稱;用等號(hào)語句定義的符號(hào)名可以被重新定義;可把等號(hào)語句看成是高級(jí)語言中的一個(gè)賦值語句,可以被多次賦值,這一點(diǎn)是與EQU不同的地方;例如:
 ABC = 10 + 200*5 ;ABC的值為1010ABC1 = 5*ABC + 21 ;ABC1的值為5071COUNT = 2*COUNT + 1 ;COUNT的值為3注意:偽指令'='和偽指令'EQU'定義符號(hào)名時(shí),凡是在程序中出現(xiàn)符號(hào)名的地方,都是用右邊的常量或表達(dá)式來替代;該語句定義一個(gè)指定的符號(hào)名,該符號(hào)名的段地址和偏移地址與下面緊跟存儲(chǔ)單元的相應(yīng)屬性相同,但是,該符號(hào)名的類型是新指定的;
 符號(hào)名 LABEL 數(shù)據(jù)類型常用的數(shù)據(jù)類型有:BYTE、WORD、DWORD、結(jié)構(gòu)類型、記錄類型、NEAR、FAR;
 其中,前五中類型是變量的類型,后面兩種類型是標(biāo)號(hào)的類型;如果格式中的'數(shù)據(jù)類型'是前面五種類型之一的話,'符號(hào)名'就是變量名;如果格式中的'數(shù)據(jù)類型'是后面的兩種類型之一的話,'符號(hào)名'就是標(biāo)號(hào)名;變量名和標(biāo)號(hào)名都具有段地址和偏移地址的屬性;
 這個(gè)LABEL定義語句中,WBUFFER與BUFFER具有完全相同的段地址和偏移地址,但是它們的數(shù)據(jù)類型不同,目的就是為了使用兩種不同類型的操作來訪問同一塊內(nèi)存區(qū);匯編語言的指令格式,目前有兩種不同的標(biāo)準(zhǔn):Windows下的匯編語言基本上都遵循Intel風(fēng)格的語法,比如:MASM、NASM;而Unix/Linux下的匯編語言基本上都遵循AT&T風(fēng)格的語法;
 [名稱[:]] 指令碼 [第一操作數(shù)][,第二操作數(shù)] ;注釋
 匯編語言的指令碼的操作數(shù)的個(gè)數(shù)可以是0、1、2個(gè);當(dāng)操作數(shù)的個(gè)數(shù)為2的時(shí)候,語句還有兩種不同的格式:
 Windows下Intel風(fēng)格的匯編語言語句格式為:
 [名稱[:]] 指令碼 目的操作數(shù)DST,源操作數(shù)SRC ;注釋
 Unix/Linux下AT&T風(fēng)格的匯編語言語句格式為:
 [名稱[:]] 指令碼 源操作數(shù)SRC,目的操作數(shù)DST ;注釋
 例如:
 CYCLE: ADD AX,02H 
;(AX)匯編語言語句格式中的'名稱'并不是所有語句都必需的,但是,如果語句中帶有'名稱',那么,大多數(shù)情況下,'名稱'都表示的是內(nèi)存中某一存儲(chǔ)單元的地址,也就是'名稱'后面各項(xiàng)在內(nèi)存中存放的第一個(gè)存儲(chǔ)單元的地址(包括該'名稱'所在段的段地址和段內(nèi)偏移地址);比如上面的指令中,CYCLE就是該語句的名稱,CYCLE表示的就是其后面的機(jī)器指令碼在內(nèi)存中存放的第一個(gè)地址;'名稱'與指令碼之間的分隔符可以是冒號(hào)':',也可以是空格字符'
 
';當(dāng)以冒號(hào)分割時(shí),該名稱代表的是一個(gè)標(biāo)號(hào);當(dāng)以空格分割時(shí),該名稱代表的可能是標(biāo)號(hào),也可能是變量;當(dāng)指令碼有多個(gè)操作數(shù)的時(shí)候,相鄰兩個(gè)操作數(shù)之間要用逗號(hào)','分割;指令碼與操作數(shù)之間必須以空格分割;匯編語言語句的注釋必須以分號(hào)';'開頭;
 匯編語言中的常數(shù)有整數(shù)、字符串;二進(jìn)制、八進(jìn)制、十進(jìn)制、十六進(jìn)制;匯編語言采用不同的后綴區(qū)分:
 B:二進(jìn)制數(shù); O:八進(jìn)制數(shù); D:十進(jìn)制數(shù); H:十六進(jìn)制數(shù);當(dāng)一個(gè)數(shù)值后面沒有后綴的時(shí)候,默認(rèn)為十進(jìn)制數(shù);字符串常數(shù)是用一對(duì)單引號(hào)('')括起來的一串字符;
 算數(shù)運(yùn)算操作符: +、-、*、/、MOD,等;取模運(yùn)算MOD是取兩數(shù)相除的余數(shù);
 邏輯運(yùn)算操作符: AND(邏輯與)、OR(邏輯或)、NOT(邏輯非)、XOR(邏輯異或);
 注意:邏輯運(yùn)算符同時(shí)又可以是邏輯運(yùn)算指令的指令碼,只有當(dāng)它們出現(xiàn)在指令的操作數(shù)部分時(shí),才是操作符;例如:
 ADD AL,0CH ADD 0FH ;第一個(gè)ADD是指令碼,第二個(gè)ADD是操作符;關(guān)系運(yùn)算操作符: EQ(相等)、NE(不等)、LT(小于)、GT(大于)、LE(小于等于)、GE(大于等于);
 匯編語言中的表達(dá)式不能單獨(dú)構(gòu)成語句,只能是語句的組成部分;
 注意:語句中表達(dá)式的求值不是在語句執(zhí)行時(shí)完成的,而是在對(duì)源程序進(jìn)行匯編鏈接時(shí)完成的.所以,語句中各表達(dá)式的值必須在匯編或鏈接時(shí)就是確定的,也就是說,表達(dá)式中各標(biāo)識(shí)符的值在匯編或鏈接時(shí)就應(yīng)該是確定的;
 標(biāo)號(hào)是由標(biāo)識(shí)符表示的指令的名稱,用于指示對(duì)應(yīng)指令的位置(地址);
 標(biāo)號(hào)具有三個(gè)屬性:段地址、偏移地址和類型;
 標(biāo)號(hào)的段地址和偏移地址屬性是指該標(biāo)號(hào)所對(duì)應(yīng)的指令所在段的段地址和段內(nèi)偏移地址;
 標(biāo)號(hào)的類型有兩種:NEAR和FAR;標(biāo)號(hào)定義成NEAR類型,表示該標(biāo)號(hào)在段內(nèi)使用,而定義成FAR類型則表示該標(biāo)號(hào)可以在段間使用;
 標(biāo)號(hào)的定義:在指令碼前面加上標(biāo)識(shí)符和冒號(hào)':';
 這條語句里面,START就是我們定義的標(biāo)號(hào),它代表指令PUSH的地址,所以,標(biāo)號(hào)可以作為程序轉(zhuǎn)移指令的操作數(shù)(即:要轉(zhuǎn)向的地址);標(biāo)號(hào)還可以采用偽指令來定義;例如:用LABEL偽指令和過程定義偽指令來定義;
 與高級(jí)語言一樣,并不是所有的操作數(shù)都是常數(shù),匯編語言也有自己的變量,變量的值在程序運(yùn)行期間是可以被改變的;
 A.定義變量:匯編語言中,變量的定義是通過偽指令來完成的;定義變量的偽指令格式如下:
 變量名 DB 表達(dá)式 ;定義字節(jié)變量,又稱單字節(jié)變量(1個(gè)連續(xù)字節(jié)),DB-->BYTE變量名 DW 表達(dá)式 ;定義字變量,又稱雙字節(jié)變量(2個(gè)連續(xù)字節(jié)),DW-->WORD變量名 DD 表達(dá)式 ;定義雙字變量,又稱四字節(jié)變量(4個(gè)連續(xù)字節(jié)),DD-->DWORD變量名 DF 表達(dá)式 ;定義六字節(jié)變量,又稱六字節(jié)變量(6個(gè)連續(xù)字節(jié)),DF-->FWORD變量名 DQ 表達(dá)式 ;定義長(zhǎng)字變量,又稱八字節(jié)變量(8個(gè)連續(xù)字節(jié)),DQ-->QWORD變量名 DT 表達(dá)式 ;定義十字節(jié)變量(10個(gè)連續(xù)字節(jié)),DT-->TBYTE;其中,變量名是一個(gè)合法的標(biāo)識(shí)符,變量名后面不能加冒號(hào)':',只能用空格;變量名不是必要的,可有可無;變量的類型由關(guān)鍵字DB、DW、DD、DQ、DT來定義;變量定義語句中的'表達(dá)式'是用于對(duì)變量進(jìn)行初始化的,可有一下幾種情況:(1).一個(gè)或多個(gè)常數(shù)或表達(dá)式;當(dāng)為多個(gè)常數(shù)或表達(dá)式時(shí),期間要用逗號(hào)隔開;如DATA1--DATA4;
 對(duì)于字節(jié)型(DB)變量,每個(gè)變量的大小為1個(gè)字節(jié),每個(gè)變量的值不能超過1個(gè)字符,每個(gè)字節(jié)內(nèi)存入一個(gè)字符的ASCII碼值,整個(gè)字符串可以在同一對(duì)單引號(hào)內(nèi)給出,這相當(dāng)于是定義了一個(gè)字符數(shù)組,如DATA5;
 對(duì)于字類型(DW)變量,每個(gè)變量的大小為2個(gè)字節(jié),每個(gè)變量的值不能超過2個(gè)字符,若為2個(gè)字符時(shí),同樣遵循高位存入高字節(jié),低位存入低字節(jié)的規(guī)則;若為1個(gè)字符,則該字符的ASCII碼值存入到低字節(jié),高字節(jié)為00,如DATA6;
 對(duì)于雙字類型(DD)變量,每個(gè)變量的大小為4個(gè)字節(jié),每個(gè)變量的值不能超過2個(gè)字符,若為2個(gè)字符,同樣遵循高位存入高字節(jié),低位存入低字節(jié)的規(guī)則;但是2個(gè)字符的值被存入到雙字變量的最低2個(gè)字節(jié)中,1個(gè)字符的值被存入到雙字變量的最低1個(gè)字節(jié)中;
 對(duì)于長(zhǎng)字類型(DQ)變量,每個(gè)變量的大小為8個(gè)字節(jié),每個(gè)變量的值不能超過2個(gè)字符,若為2個(gè)字符,同樣遵循高位存入高字節(jié),低位存入低字節(jié)的規(guī)則;但是2個(gè)字符的值被存入到長(zhǎng)字變量的最低2個(gè)字節(jié)中,1個(gè)字符的值被存入到長(zhǎng)字變量的最低1個(gè)字節(jié)中;
 (3).一個(gè)問號(hào)'?',表示該變量的值不確定,即:該變量所表示的內(nèi)存單元中的內(nèi)容是不確定的,或者說是,當(dāng)表達(dá)式為問號(hào)時(shí),變量所對(duì)應(yīng)的內(nèi)存區(qū)中并沒有存入新的值,而只是預(yù)留出了相應(yīng)的存儲(chǔ)空間;如DATA7、DATA8
 (4).重復(fù)方式;此時(shí)的格式為: 重復(fù)次數(shù) DUP(表達(dá)式);重復(fù)方式指出表達(dá)式的值可以重復(fù)地存儲(chǔ)到變量對(duì)應(yīng)的內(nèi)存區(qū)中,重復(fù)的次數(shù)由偽指令給出,相當(dāng)于定義數(shù)組;如DATA9、DATA10
 DATA2 DW 0204H,1000H ;2字節(jié)變量DATA3 DB (-1*3),(15/3) ;1字節(jié)變量DATA4 DD 123456H ;4字節(jié)變量DATA5 DB '0123' ;字符串變量,相當(dāng)于一個(gè)字符數(shù)組DATA6 DW 'AB','C','D' ;字符串變量,相當(dāng)于一個(gè)字符串?dāng)?shù)組;DATA7 DB ? ;1字節(jié)變量,未初始化DATA8 DD ? ;4字節(jié)變量,未初始化DATA9 DB 5 DUP(0) ;1字節(jié)變量,用5個(gè)0初始化,相當(dāng)于是一個(gè)具有5個(gè)DB型元素的數(shù)組DATA10 DW 3 DUP(?) ;2字節(jié)變量,未初始化,相當(dāng)于是一個(gè)具有3個(gè)DW型元素的數(shù)組變量定義語句中偽指令的功能是在變量名所對(duì)應(yīng)的地址開始的內(nèi)存區(qū)依次存入表達(dá)式中的各項(xiàng)值,表達(dá)式中的每項(xiàng)值所占用內(nèi)存字節(jié)數(shù)與變量的類型對(duì)應(yīng);
 總結(jié):一個(gè)變量的變量名實(shí)際上就代表了該變量所對(duì)應(yīng)的內(nèi)存區(qū)在內(nèi)存段中的有效地址(偏移地址);高地址是指地址值相對(duì)較大,低地址是指地址值相對(duì)較小,高地址與低地址是相對(duì)而言的;
 B.偏移地址(OFFSET):變量所在段內(nèi)的偏移地址;
 C.類型(TYPE):變量的類型定義了每個(gè)變量所占用的內(nèi)存字節(jié)數(shù),對(duì)于DB、DW、DD、DQ、DT類型定義的變量所占用的內(nèi)存字節(jié)數(shù)分別是1、2、4、8、10;通常又將DB、DW、DD類型所定義的變量分別成為BYTE類型、WORD類型、DWORD類型變量;
 標(biāo)識(shí)符種類 字節(jié)變量 字變量 雙字變量 近標(biāo)號(hào)NEAR 遠(yuǎn)標(biāo)號(hào)FAR
 D.長(zhǎng)度(LENGTH):變量定義時(shí),一個(gè)變量名所定義的變量個(gè)數(shù);在含有DUP操作符的變量定義中,變量名所定義的變量個(gè)數(shù)為定義格式中的重復(fù)次數(shù);在其它各種變量定義中,每個(gè)變量名所定義的變量個(gè)數(shù)均為1個(gè);
 E.大小(SIZE):變量定義語句中,分配給同一個(gè)變量名的所有變量的總的字節(jié)數(shù),其值為該變量的類型與長(zhǎng)度的成績(jī);
 其中,段地址、偏移地址和類型屬性是變量的主屬性,而長(zhǎng)度和大小屬性是變量的輔助屬性;
 SEG SEG 變量名或標(biāo)號(hào) 取出變量名或標(biāo)號(hào)所在段的段地址
 OFFSET OFFSET 變量名或標(biāo)號(hào) 取出變量名或標(biāo)號(hào)所在段內(nèi)的偏移地址
 TYPE TYPE 變量名或標(biāo)號(hào) 取出變量名或標(biāo)號(hào)的類型(變量所占用的字節(jié)數(shù))
 LENGTH LENGTH 變量名 取出變量的長(zhǎng)度
 這些操作符不能單獨(dú)構(gòu)成語句,只能作為表達(dá)式的組成部分,并且表達(dá)式的求值也是在匯編過程中完成的;
 6.強(qiáng)制類型轉(zhuǎn)換操作符PTR
 格式:數(shù)據(jù)類型 PTR 地址表達(dá)式
 格式中的'數(shù)據(jù)類型'可以是BYTE、WORD、DWORD、NEAR、FAR;前三種類型是變量的類型,后兩種類型是標(biāo)號(hào)的類型;格式中的表達(dá)式可以是變量、標(biāo)號(hào)、其它地址表達(dá)式;
 PTR操作符的功能是用來重新定義已定義的變量或標(biāo)號(hào)的類型,其作用域只在當(dāng)前語句中; 例如:
 這條指令中,是把DATA1的類型轉(zhuǎn)換為BYTE類型,然后把AL中的內(nèi)容存放到DATA1的最低一個(gè)字節(jié)中;作用域只在這條MOV語句中,過了這條語句,DATA1仍然是DW類型,即:DATA1原來的類型并沒有被修改;
 符合數(shù)據(jù)類型,除了用DUP定義的重復(fù)數(shù)據(jù)類型之外,與C/C++語言一樣,匯編語言中也有結(jié)構(gòu)體類型、聯(lián)合類型、記錄類型;
 結(jié)構(gòu)類型名 STRUC [對(duì)齊類型Alignment][,NONUNIQUE]說明:結(jié)構(gòu)體中的字段名可有可無;若有字段名,則字段名必須唯一,每個(gè)字段可獨(dú)立存取;若沒有字段名,則通過偏移量來存取;
 對(duì)齊方式Alignment:定義每個(gè)字段的字節(jié)對(duì)齊邊界,對(duì)齊值有1、2、4、8、16字節(jié)對(duì)齊,值必須是2的冪次方;對(duì)齊類似于C/C++中結(jié)構(gòu)體字段的對(duì)齊;
 NONUNIQUE:要求結(jié)構(gòu)體中的字段必須用全名才能訪問;
 結(jié)構(gòu)體中的字段可以有字段名,也可以沒有字段名;有字段名的字段可直接使用該字段名來訪問,沒有字段名的字段可用使用該字段在結(jié)構(gòu)體中的偏移量來訪問;
 NAME DB 10 DUP(?) ;有名字段,偏移量為4字段值列表中的各個(gè)字段之間用逗號(hào)','分割,字段值的排列順序及類型應(yīng)該與該結(jié)構(gòu)定義時(shí)說明的各個(gè)字段相一致;如果結(jié)構(gòu)變量中某個(gè)字段的值使用定義結(jié)構(gòu)時(shí)說明的缺省值,那么可用逗號(hào)來表示;如果所有字段都使用定義結(jié)構(gòu)體時(shí)說明的各個(gè)字段的缺省值,則可省去字段值列表,只需保留一對(duì)尖括號(hào)''即可;
 Per1 PERSON ;所有字段都是用默認(rèn)值Per3 PERSON ;第二個(gè)字段使用默認(rèn)值;
 這種引用方式與高級(jí)語言中的引用方式完全一致;另外,還可以使用偏移量來訪問某個(gè)字段;
 方式2:使用字段的在結(jié)構(gòu)體中的偏移量來引用
 LEA SI,Per3 ;取變量Per3對(duì)應(yīng)內(nèi)存塊的有效地址
 MOV AX,[SI+4] ;寄存器相對(duì)尋址,4是字段NAME的偏移量
 [聯(lián)合體類型名] UNION [對(duì)齊方式Alignment][,NONUNIQUE]說明:聯(lián)合體類型中的各個(gè)字段相互覆蓋,即:同樣的存儲(chǔ)單元被多個(gè)不同類型的字段所對(duì)應(yīng),并且每個(gè)字段在聯(lián)合體類型中的偏移量都是0;聯(lián)合體類型所占用的字節(jié)數(shù)是其所有字段所占字節(jié)數(shù)的最大值,即:聯(lián)合體所占用的字節(jié)數(shù)是這個(gè)聯(lián)合體的所有字段中占用字節(jié)數(shù)最多的那個(gè)字段占用的字節(jié)數(shù);
 對(duì)齊方式Alignment:可用1、2、4、8、16個(gè)字節(jié)來指定聯(lián)合體中各個(gè)字段字節(jié)的對(duì)齊邊界,其缺省的對(duì)齊邊界是1字節(jié);還可用使用偽指令A(yù)LIGN或EVEN來重新定界,也可使用命令行選項(xiàng)/Zp來定界;
 NONUNIQUE:要求聯(lián)合體類型中的字段必須使用全名才能訪問;
 聯(lián)合體類型的變量只能使用第一個(gè)字段的數(shù)據(jù)類型來進(jìn)行初始化;例如:DATE1 DATE ;定義一個(gè)聯(lián)合體類型變量DATE1,并使用第一個(gè)字段的數(shù)據(jù)類型進(jìn)行初始化
 DATE2 DATE ;初始化錯(cuò)誤,只能使用第一個(gè)字段的數(shù)據(jù)類型進(jìn)行初始化;
 MOV DATE1.YEAR,2012 ;給聯(lián)合體類型變量字段賦值MOV AL,DATE1.MONTH ;AL=07MOV BX,DATE1.YEAR ;BX=2012MOV DATE1.MONTH,08 ;月份置為8月匯編語言中的記錄類型與高級(jí)語言中的記錄類型不同,在匯編語言中,記錄類型是為按照二進(jìn)制位存取數(shù)據(jù)提供方便的;記錄類型的說明要用到另一個(gè)關(guān)鍵字RECORD,格式如下:
 其中,'字段'代表: 字段名:寬度[=初始值表達(dá)式]
 說明:記錄名代表該記錄類型;記錄類型可以由多個(gè)字段組成,相鄰兩個(gè)字段之間用逗號(hào)隔開;記錄類型中字段的屬性包括字段名、寬度和初始值;記錄類型中,字段的'寬度'屬性表示該字段所占用的二進(jìn)制位數(shù),它必須是一個(gè)常數(shù),并且所有字段的寬度之和不能大于16(即:有字段的寬度之和大于8,則系統(tǒng)會(huì)自動(dòng)為該記錄類型分配2字節(jié)的空間,否則只分配1個(gè)字節(jié)的空間;記錄類型的最后一個(gè)字段排在所分配空間的最低位,然后對(duì)記錄中的字段依次'從右向左'分配二進(jìn)制位,左邊沒有分完的二進(jìn)制位自動(dòng)補(bǔ)0;初值表達(dá)式給出的是該字段的缺省值,如果初值超過了該字段所表示的范圍,那么,在匯編時(shí)將產(chǎn)生錯(cuò)誤提示信息,如果某字段沒有初值表達(dá)式,則其初值為0;
 COLOR RECORD BLINK:1,BACK:3=0,INTENSE:1=1,FORE:3
 該COLOR類型的二進(jìn)制位分布如下圖所示:
 該類型的各個(gè)字段寬度為:1、3、1、3,所以,該記錄占用8個(gè)二進(jìn)制位,系統(tǒng)為它分配1個(gè)字節(jié);
 FLOAT RECORD DSIGN:1,DATA:8,ESIGN:1,EXP:4
 該FLOAT類型的二進(jìn)制位分布如下圖所示:
 該類型的總寬度是14個(gè)二進(jìn)制位,所以,系統(tǒng)為它分配2個(gè)字節(jié)的空間;
 說明:變量名就是該記錄類型的變量名,它可缺省,則不能使用符號(hào)名來訪問該內(nèi)存單元;字段值列表是用于給各個(gè)字段賦初值,相鄰兩個(gè)字段值之間用逗號(hào)','隔開,其字段值的排列順序及大小應(yīng)該按照記錄類型定義時(shí)說明的各個(gè)字段的順序和大小來排列;如果記錄類型變量的某個(gè)字段使用默認(rèn)值,那么,可用逗號(hào)來表示,如果所有字段都是用默認(rèn)值,則可省去字段值列表,但必須保留一對(duì)尖括號(hào)'';
 操作符WIDTH和MASK是專用于記錄類型的操作符,利用它們可用得到記錄類型的不同屬性;
 WIDTH:用于返回記錄或其字段的二進(jìn)制位數(shù),即:記錄類型或記錄類型字段的寬度;書寫格式如下:
 例如:記錄類型COLOR,那么,WIDTH COLOR的值為8,WIDTH BACK的值為3,WIDTH BLINK的值為1;
 MASK:它返回一個(gè)8位或16位的二進(jìn)制數(shù),在該二進(jìn)制數(shù)中,被指定記錄或字段使用的對(duì)應(yīng)位的值為1,否則,其值為0;書寫格式如下:
 例如:記錄類型FLOAT,那么,MASK EXP的值為000FH,MASK DATA的值為1FE0H,MASK DSIGN的值為2000H;
 記錄字段:記錄字段名是一個(gè)特殊的操作符,它本身也是一個(gè)操作數(shù),其返回值是該字段移到該字段所在記錄的最低位所需要的位數(shù),即:該字段最低位在記錄中的位置;MOV CL,EXP 相當(dāng)于 MOV CL,0MOV CL,DATA 相當(dāng)于 MOV CL,5
 已知某一數(shù)據(jù)類型,程序員可以定義這個(gè)數(shù)據(jù)類型的別名或指針類型.表達(dá)這種定義的偽指令是TYPEDEF,其定義形式如下:
 新數(shù)據(jù)類型名 TYPEDEF [位距][PTR] 已知數(shù)據(jù)類型
 CHAR TYPEDEF BYTE ;給BYTE類型定義另外一個(gè)別名CHAR,C++中就是: typedef BYTE CHAR
 PCHAR TYPEDEF PTR CHAR ;定義一個(gè)字符指針數(shù)據(jù)類型PCHAR,C++中就是:typedef PTR CHAR PCHAR,即:typedef char* PCHAR
 CH1 CHAR 'ABCDEF' ;定義一個(gè)字符串常量
 PCH1 PCHAR CH1 ;定義一個(gè)指向字符串常量CH1的變量
 這個(gè)功能類似于C++語言中的typedef語句;
 SEG(段地址)、OFFSET(偏移量)、TYPE(數(shù)據(jù)類型)、LENGTH(變量長(zhǎng)度)、SIZE(變量容量)
 WIDTH(記錄/記錄字段的寬度)、MASK(記錄/記錄字段的屏蔽位),等等;
 其中,HIGH和LOW分別用于選取表達(dá)式計(jì)算結(jié)果的高8位和低8位,使用格式如下:9.運(yùn)算符和操作符的優(yōu)先級(jí):
 優(yōu)先級(jí): 高 LENGTH、SIZE、WIDTH、MASK、()、[]、.(用于結(jié)構(gòu)字段)、(用于記錄類型)
 ↓ PTR、SEG、OFFSET、TYPE、THIS、:(用于段超越前綴)地址表達(dá)式是計(jì)算存儲(chǔ)器單元地址的表達(dá)式,它可由標(biāo)號(hào)、變量名和由方括號(hào)'[]'括起來的基址或變址寄存器組成;其計(jì)算結(jié)果表示一個(gè)存儲(chǔ)器單元的地址,而不是該存儲(chǔ)器單元中的值;
 注意:匯編語言中,對(duì)地址數(shù)值的運(yùn)算都是以字節(jié)為單位的,而不是以數(shù)據(jù)類型的大小為單位的;例如:
 則,地址表達(dá)式W1+1處的內(nèi)存單元中的數(shù)據(jù)是7812H,而不是5678H;W1+1表示W(wǎng)1為起始地址,其下一個(gè)字節(jié)單元的地址,W1+2表示從地址W1出開始,其后2個(gè)字節(jié)單元地址;
 在程序中,經(jīng)常會(huì)用到一些常數(shù)或數(shù)值表達(dá)式,并把它們直接寫在指令值,當(dāng)時(shí)當(dāng)需要修改的時(shí)候,就要對(duì)它們逐一進(jìn)行修改,這無疑就增加了維護(hù)程序的工作量,而且每個(gè)常量或表達(dá)式所代表的含義也容易忘記;于是,匯編語言提供了為常量或表達(dá)式定義一個(gè)符號(hào)名的方法;一旦定義了符號(hào)名,在指令中就可以直接使用它們了;這個(gè)功能就類似于C語言中使用宏定義指令#define定義常量的功能相似,也與C++中使用const關(guān)鍵字定義常量的功能相似;
 作用:左邊的符號(hào)名代表右邊的表達(dá)式;
 注意:等價(jià)語句不會(huì)給符號(hào)名分配存儲(chǔ)空間,符號(hào)名不能與其它符號(hào)名重名,即:符號(hào)名必須唯一;符號(hào)名也不能被重新定義;程序中凡是出現(xiàn)'表達(dá)式'的地方,都使用'符號(hào)名'來替換;
 (2).使用符號(hào)名代表常量或表達(dá)式
 把一個(gè)常量或表達(dá)式定義成一個(gè)具有一定含義的符號(hào)名之后,在程序中就可以用該符號(hào)名來代表該常量或表達(dá)式;例如:
 NUMBER EQU 100 ;給緩沖區(qū)的長(zhǎng)度取一個(gè)符號(hào)名CR EQU 13 ;給'回車'符的ASCII碼定義一個(gè)符號(hào)名LN EQU 10 ;給'換行'符的ASCII碼定義一個(gè)符號(hào)名GREETING EQU 'How are you!'(4).用符號(hào)名代表關(guān)鍵字或指令碼MOVE EQU MOV ;給指令碼MOV取另外一個(gè)符號(hào)名MOVECOUNTER EQU CX ;給寄存器CX取一個(gè)叫做'計(jì)數(shù)器'的符號(hào)名匯編語言提供了使用等號(hào)'='來定義符號(hào)常數(shù)的方法,即:可用符號(hào)名代表一個(gè)常數(shù);一般格式如下:數(shù)值表達(dá)式在匯編時(shí)應(yīng)該可以計(jì)算出值,它不能含有向前引用的符號(hào)名稱;用等號(hào)語句定義的符號(hào)名可以被重新定義;可把等號(hào)語句看成是高級(jí)語言中的一個(gè)賦值語句,可以被多次賦值,這一點(diǎn)是與EQU不同的地方;例如:
 ABC = 10 + 200*5 ;ABC的值為1010ABC1 = 5*ABC + 21 ;ABC1的值為5071COUNT = 2*COUNT + 1 ;COUNT的值為3注意:偽指令'='和偽指令'EQU'定義符號(hào)名時(shí),凡是在程序中出現(xiàn)符號(hào)名的地方,都是用右邊的常量或表達(dá)式來替代;該語句定義一個(gè)指定的符號(hào)名,該符號(hào)名的段地址和偏移地址與下面緊跟存儲(chǔ)單元的相應(yīng)屬性相同,但是,該符號(hào)名的類型是新指定的;
 符號(hào)名 LABEL 數(shù)據(jù)類型
 常用的數(shù)據(jù)類型有:BYTE、WORD、DWORD、結(jié)構(gòu)類型、記錄類型、NEAR、FAR;
 其中,前五中類型是變量的類型,后面兩種類型是標(biāo)號(hào)的類型;如果格式中的'數(shù)據(jù)類型'是前面五種類型之一的話,'符號(hào)名'就是變量名;如果格式中的'數(shù)據(jù)類型'是后面的兩種類型之一的話,'符號(hào)名'就是標(biāo)號(hào)名;變量名和標(biāo)號(hào)名都具有段地址和偏移地址的屬性;
 這個(gè)LABEL定義語句中,WBUFFER與BUFFER具有完全相同的段地址和偏移地址,但是它們的數(shù)據(jù)類型不同,目的就是為了使用兩種不同類型的操作來訪問同一塊內(nèi)存區(qū);
 
 
 |