版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
會(huì)計(jì)學(xué)1ch5匯編語(yǔ)言程序設(shè)計(jì)
任何計(jì)算機(jī)實(shí)際上只能直接識(shí)別設(shè)計(jì)微處理器時(shí)所規(guī)定好的,一整套用“0”、“1”數(shù)字代碼表示的機(jī)器指令。這些機(jī)器指令的全體是指令系統(tǒng)。不同類型的CPU,其機(jī)器語(yǔ)言必然是不同的。這種直接用機(jī)器指令來(lái)編制計(jì)算機(jī)程序的方法就稱為機(jī)器語(yǔ)言程序設(shè)計(jì)。
《微機(jī)原理及應(yīng)用》課程實(shí)驗(yàn)教學(xué)用的單板計(jì)算機(jī)就是直接采用機(jī)器語(yǔ)言編程的機(jī)器。這種直接用機(jī)器語(yǔ)言編程的方法難度大,閱讀、查錯(cuò)和修改程序也很不方便。通常,只有當(dāng)編程者對(duì)CPU指令系統(tǒng)比較熟悉,編寫(xiě)的程序較短時(shí),才有可能直接用機(jī)器語(yǔ)言來(lái)編寫(xiě)計(jì)算機(jī)程序。但是,單板計(jì)算機(jī)對(duì)硬件操作很直觀,可以幫助大家了解和理解計(jì)算機(jī)在實(shí)際中的應(yīng)用。第1頁(yè)/共274頁(yè)
2.高級(jí)語(yǔ)言(HighLevelLanguage)
如果說(shuō)機(jī)器語(yǔ)言是面向機(jī)器的語(yǔ)言,那么高級(jí)語(yǔ)言(如BASIC,F(xiàn)ORTRAN等,C等)則是“面向過(guò)程”的語(yǔ)言。利用高級(jí)語(yǔ)言編程,程序員可以完全不考慮機(jī)器的結(jié)構(gòu)特點(diǎn),不必了解和熟記機(jī)器的指令系統(tǒng),僅使用一些接近人們書(shū)寫(xiě)習(xí)慣的英語(yǔ)和數(shù)學(xué)表達(dá)式形式的語(yǔ)句去編制程序。利用高級(jí)語(yǔ)言編寫(xiě)的程序與問(wèn)題本身的數(shù)學(xué)模型之間有著良好的對(duì)應(yīng)關(guān)系,可在各種機(jī)器上通用(不同機(jī)器之間僅做少量修改)。但是,用高級(jí)語(yǔ)言編寫(xiě)的源程序并不能在機(jī)器上直接執(zhí)行,需要被翻譯成對(duì)應(yīng)的目標(biāo)程序(即機(jī)器語(yǔ)言程序),機(jī)器才能運(yùn)行。把具有這種翻譯作用的程序稱為解釋程序或編譯程序,如圖5.1所示。第2頁(yè)/共274頁(yè)圖5.1編譯程序的功能示意圖
由于高級(jí)語(yǔ)言程序是在未考慮機(jī)器的結(jié)構(gòu)特點(diǎn)的條件下編寫(xiě)的,因而它就不能充分利用某種具體CPU所具有的某些特性,而通過(guò)編譯或解釋程序生成的目標(biāo)程序往往比較冗長(zhǎng),占有較多的內(nèi)存空間,執(zhí)行時(shí)間也比較長(zhǎng),這就限制了它在某些場(chǎng)合下的運(yùn)用。例如,實(shí)時(shí)的數(shù)據(jù)采集、檢測(cè)和在線的實(shí)時(shí)控制等,往往要求程序的目標(biāo)代碼盡可能少占內(nèi)存并有盡可能快的執(zhí)行速度,在這些場(chǎng)合下,使用高級(jí)語(yǔ)言編寫(xiě)的程序常常不能滿足要求。第3頁(yè)/共274頁(yè)
3.匯編語(yǔ)言(AssemblyLanguage)
人們?yōu)榱藬[脫機(jī)器語(yǔ)言編程中原始而低級(jí)的狀態(tài),就設(shè)法采用一組字母、數(shù)字或字符來(lái)代替機(jī)器指令,這樣就產(chǎn)生了匯編語(yǔ)言的概念和方法。匯編語(yǔ)言是一種采用助記符表示的程序設(shè)計(jì)語(yǔ)言,即用助記符來(lái)表示指令的操作碼和操作數(shù),用標(biāo)號(hào)或符號(hào)代表地址、常量或變量。助記符一般都是英文字的縮寫(xiě),以方便人們書(shū)寫(xiě)、閱讀和檢查。實(shí)際上,用匯編語(yǔ)言編寫(xiě)的匯編語(yǔ)言源程序就是機(jī)器語(yǔ)言程序的符號(hào)表示,匯編語(yǔ)言源程序與其經(jīng)過(guò)匯編所產(chǎn)生的目標(biāo)代碼程序之間有明顯的一一對(duì)應(yīng)關(guān)系,故也稱匯編語(yǔ)言為符號(hào)語(yǔ)言。第4頁(yè)/共274頁(yè)
用匯編語(yǔ)言編寫(xiě)程序能夠直接利用硬件系統(tǒng)的特性(如寄存器、標(biāo)志、中斷系統(tǒng)等)直接對(duì)位、字節(jié)、字寄存器或存儲(chǔ)單元、I/O端口進(jìn)行處理,同時(shí)也能直接使用CPU指令系統(tǒng)和指令系統(tǒng)提供的各種尋址方式,編制出高質(zhì)量的程序,這樣的程序不但占用內(nèi)存空間少,而且執(zhí)行速度快。當(dāng)然,由于源程序和所要解決的問(wèn)題的數(shù)學(xué)模型之間的關(guān)系不夠直觀,使得匯編語(yǔ)言程序設(shè)計(jì)需要較多的軟件開(kāi)發(fā)時(shí)間,也增加了程序設(shè)計(jì)過(guò)程中出錯(cuò)的可能性。用匯編語(yǔ)言編寫(xiě)的源程序也需要翻譯成目標(biāo)程序才能被機(jī)器執(zhí)行。這個(gè)翻譯過(guò)程稱為匯編,完成匯編任務(wù)的程序稱為匯編程序,如圖5.2所示。第5頁(yè)/共274頁(yè)圖5.2匯編程序的功能示意圖
由于這種符號(hào)化的語(yǔ)言使用了用英文字母縮寫(xiě)表示的助記符,因此便于識(shí)別與記憶。第6頁(yè)/共274頁(yè)
匯編程序是最早也是最成熟的一種系統(tǒng)軟件。它除了能夠?qū)R編語(yǔ)言源程序翻譯成機(jī)器語(yǔ)言程序這一主要功能外,還能夠根據(jù)用戶的要求自動(dòng)分配存儲(chǔ)區(qū)域(包括程序區(qū)、數(shù)據(jù)區(qū)、暫存區(qū)等);自動(dòng)地把各種進(jìn)位制數(shù)轉(zhuǎn)換成二進(jìn)制數(shù),把字符轉(zhuǎn)換成ASCII碼,計(jì)算表達(dá)式的值等;自動(dòng)對(duì)源程序進(jìn)行檢查,給出錯(cuò)誤信息(如非法格式,未定義的助記符、標(biāo)號(hào),漏掉操作數(shù)等)等。具有這些功能的匯編程序又稱為基本匯編(或小匯編ASM)。在基本匯編的基礎(chǔ)上,進(jìn)一步允許在源程序中把一個(gè)指令序列定義為一條宏指令的匯編程序,就叫做宏匯編(MASM)。它包含全部ASM功能,還增加了宏指令、結(jié)構(gòu)、記錄等高級(jí)匯編語(yǔ)言功能。第7頁(yè)/共274頁(yè)問(wèn)題:有高級(jí)語(yǔ)言,為什么還要學(xué)習(xí)和使用匯編語(yǔ)言?原因:
(1)匯編語(yǔ)言非常接近機(jī)器語(yǔ)言程序,通過(guò)編制匯編語(yǔ)言程序,可以更清楚地了解計(jì)算機(jī)的工作過(guò)程。
(2)現(xiàn)在的微機(jī)系統(tǒng)中,底層的一些功能仍然靠匯編語(yǔ)言程序來(lái)實(shí)現(xiàn)。
(3)匯編語(yǔ)言程序的效率通常高于高級(jí)語(yǔ)言程序。第8頁(yè)/共274頁(yè)5.2匯編語(yǔ)言源程序的格式例5.1
要求將兩個(gè)5字節(jié)十六進(jìn)制數(shù)相加。解:為實(shí)現(xiàn)上述功能,可以編寫(xiě)出以下匯編語(yǔ)言源程序。DATA SEGMENT ;定義數(shù)據(jù)段
DATA1DB0F8H,60H,0ACH,74H,3BH;被加數(shù)
DATA2DB0C1H,36H,9EH,0D5H,20H;加數(shù)DATA ENDS ;數(shù)據(jù)段結(jié)束CODESEGMENT ;定義代碼段
ASSUMECS:CODE,DS:DATA第9頁(yè)/共274頁(yè)START: MOV AX,DATA MOV DS,AX ;初始化DS MOV CX,5 ;循環(huán)次數(shù)送CX MOV SI,0 ;置SI初值為0 CLC ;清CF標(biāo)志LOOPER: MOV AL,DATA2[SI] ;取一個(gè)字節(jié)加數(shù)
ADC DATA1[SI],AL ;與被加數(shù)相加第10頁(yè)/共274頁(yè) INC SI ;SI加1 DEC CX ;CX減1 JNZ LOOPER ;若不等于0,轉(zhuǎn)LOOPER MOV AH,4CH INT 21H ;返回DOSCODE ENDS ;代碼段結(jié)束
END START ;源程序結(jié)束第11頁(yè)/共274頁(yè)程序結(jié)構(gòu)程序由數(shù)條語(yǔ)句構(gòu)成,每條語(yǔ)句占一行。指令性語(yǔ)句(指令語(yǔ)句)
指示性語(yǔ)句(偽指令語(yǔ)句)
分段結(jié)構(gòu)程序按段編寫(xiě),與8086內(nèi)存分段編址相對(duì)應(yīng)。每段由偽操作SEGMENT開(kāi)始、由ENDS結(jié)束。程序最后為END結(jié)束語(yǔ)句,后跟啟動(dòng)地址。啟動(dòng)地址指示程序開(kāi)始執(zhí)行的第一條語(yǔ)句。程序中設(shè)有返回DOS的功能。使程序執(zhí)行完后返回DOS系統(tǒng)的命令接受狀態(tài)。
程序中用到內(nèi)存操作數(shù)時(shí),應(yīng)按操作數(shù)的尋址方式,給相應(yīng)的段寄存器賦值匯編語(yǔ)言程序結(jié)構(gòu):movs.asmaaSEGMENT
;數(shù)據(jù)段1str1DB'Hello!’aaENDSbbSEGMENT
;數(shù)據(jù)段2str2DB6dup(?)bbENDSccSEGMENT
;代碼段
ASSUMECS:cc,DS:aa,ES:bbstart:CLDMOVAX,aaMOVDS,AXLEASI,str1MOVAX,SEGstr2MOVES,AXMOVDI,OFFSETstr2MOVCX,6REPMOVSB
MOVAH,4CHINT21H
;返回DOSccENDS
ENDstart;指示程序結(jié)束第12頁(yè)/共274頁(yè)5.2.1分段結(jié)構(gòu)
由例5.1可以看出,匯編語(yǔ)言源程序的結(jié)構(gòu)是分段結(jié)構(gòu)形式,一個(gè)匯編語(yǔ)言源程序由若干段(SEGMENT)組成,每個(gè)段以SEGMENT語(yǔ)句開(kāi)始,以ENDS語(yǔ)句結(jié)束。整個(gè)源程序的結(jié)尾是END語(yǔ)句。這里所說(shuō)的匯編語(yǔ)言源程序中的段與前面討論的CPU管理的存儲(chǔ)器的段,既有聯(lián)系,又在概念上有所區(qū)別。我們已經(jīng)知道,微處理器對(duì)存儲(chǔ)器的管理是分段的,因此,在匯編語(yǔ)言程序中也要求分段組織指令、數(shù)據(jù)和堆棧,以便將源程序匯編成為目標(biāo)程序后,可以分別裝入存儲(chǔ)器的相應(yīng)段中。第13頁(yè)/共274頁(yè)
但是,以8086/8088CPU為例,它有四個(gè)段寄存器(CS,ES,SS和DS),因此CPU對(duì)存儲(chǔ)器按照四個(gè)物理段進(jìn)行管理,即數(shù)據(jù)段、附加段、堆棧段和代碼段。任何時(shí)侯CPU只能訪問(wèn)四個(gè)物理段。而在匯編語(yǔ)言源程序中,設(shè)置段的自由度比較大。例如,一個(gè)源程序中可以有多個(gè)數(shù)據(jù)段或多個(gè)代碼段等等。一般來(lái)說(shuō),匯編語(yǔ)言源程序中段的數(shù)目可以根據(jù)實(shí)際需要而設(shè)定。為了和CPU管理的存儲(chǔ)器物理段相區(qū)別,我們將匯編語(yǔ)言程序中的段稱為邏輯段。在不致發(fā)生混淆的地方,有時(shí)簡(jiǎn)稱為段。第14頁(yè)/共274頁(yè)
在例5.1的簡(jiǎn)單源程序中只有兩個(gè)邏輯段,一個(gè)邏輯段的名字是DATA,其中存放著與程序有關(guān)的數(shù)據(jù),稱為邏輯數(shù)據(jù)段;另一個(gè)邏輯段的名字是CODE,其中包含著程序的指令,稱為邏輯代碼段。每個(gè)段內(nèi)均有若干行語(yǔ)句(STATEMENT),因此,可以說(shuō)一個(gè)匯編源程序是由一行一行的語(yǔ)句組成的。下面我們來(lái)討論匯編語(yǔ)言語(yǔ)句的類型和組成。第15頁(yè)/共274頁(yè)5.2.2匯編語(yǔ)言語(yǔ)句的類型和格式
1.語(yǔ)句的類型匯編語(yǔ)言源程序中的語(yǔ)句可以分為兩種類型:指令語(yǔ)句和偽指令語(yǔ)句。
(1)指令語(yǔ)句:它是能產(chǎn)生目標(biāo)代碼,CPU可以執(zhí)行的能完成特定功能的語(yǔ)句。
(2)偽指令語(yǔ)句:它是一種不產(chǎn)生目標(biāo)代碼的語(yǔ)句,它僅僅在匯編過(guò)程中告訴匯編程序應(yīng)如何匯編。例如,告訴匯編程序已寫(xiě)出的匯編語(yǔ)言源程序有幾個(gè)段,段的名字是什么;定義變量,定義過(guò)程,給變量分配存儲(chǔ)單元,給數(shù)字或表達(dá)式命名等。顯然,偽指令語(yǔ)句是匯編程序在匯編時(shí)使用的。第16頁(yè)/共274頁(yè)2.語(yǔ)句的格式指令語(yǔ)句與偽指令語(yǔ)句的格式是類似的。一般情況下,匯編語(yǔ)言的語(yǔ)句可以由1~4部分構(gòu)成:
[名字]助記符[操作數(shù)][;注釋]
其中帶方括號(hào)的部分表示任選項(xiàng),可以有,也可以沒(méi)有。例5.1中有如下語(yǔ)句:LOOPER:MOVAL,DATA2[SI];取一個(gè)字節(jié)加數(shù)這是一條指令語(yǔ)句,其中:“LOOPER:”是名字,“MOV”是指令助記符,“AL,DATA2[SI]”是操作數(shù),“;”后面是注釋部分。第17頁(yè)/共274頁(yè)
例.DATA1DB0F8H,60H,0ACH,74H,3BH;定義被加數(shù)這是一條偽指令語(yǔ)句,其中:“DATA1”是名字,“DB”是偽指令定義符,“0F8H,60H,0ACH,74H,3BH”是操作數(shù),“;”后面是注釋部分。
下面,對(duì)匯編語(yǔ)言中的各個(gè)組成部分進(jìn)行討論。第18頁(yè)/共274頁(yè)語(yǔ)句結(jié)構(gòu)
dataSEGMENT;數(shù)據(jù)段varDB?dataENDScodeSEGMENT;代碼段
ASSUMECS:code,DS:datastart:MOVAX,dataMOVDS,AXMOVvar,CLMOVAH,4CHINT21H;返回DOScodeENDS
ENDstart例:第19頁(yè)/共274頁(yè)1)名字匯編語(yǔ)言語(yǔ)句的第一個(gè)組成部分是名字(Name)。在指令語(yǔ)句中,這個(gè)名字是一個(gè)標(biāo)號(hào)。指令語(yǔ)句中的標(biāo)號(hào)實(shí)質(zhì)上是指令的符號(hào)地址。并非每條指令語(yǔ)句必須有標(biāo)號(hào),但如果一條指令前面有一標(biāo)號(hào),則程序中其他地方就可以引用這個(gè)標(biāo)號(hào)。在例5.1中,START、LOOPER就是標(biāo)號(hào)。標(biāo)號(hào)后面通常有一個(gè)冒號(hào)。標(biāo)號(hào)有三種屬性:段、偏移量和類型。
第20頁(yè)/共274頁(yè)①標(biāo)號(hào)的段屬性是定義標(biāo)號(hào)在程序段的段地址。當(dāng)程序中引用一個(gè)標(biāo)號(hào)時(shí),該標(biāo)號(hào)的段值應(yīng)在CS寄存器中。②標(biāo)號(hào)的偏移量屬性表示標(biāo)號(hào)所在段的起始地址到定義該標(biāo)號(hào)的地址之間的字節(jié)數(shù)。偏移量是一個(gè)16位無(wú)符號(hào)數(shù)。③標(biāo)號(hào)的類型屬性有兩種:NEAR和FAR。NEAR標(biāo)號(hào)可以在段內(nèi)被引用,地址指針為2字節(jié);FAR標(biāo)號(hào)可以在其他段被引用,地址指針為4字節(jié)。如果定義一個(gè)標(biāo)號(hào)時(shí)后面跟著冒號(hào),則匯編程序確認(rèn)其類型為NEAR。第21頁(yè)/共274頁(yè)
偽指令語(yǔ)句中的名字可以是變量名、段名、過(guò)程名。與指令語(yǔ)句中的標(biāo)號(hào)不同,這些偽指令語(yǔ)句中的名字并不總是任選的,有些偽指令規(guī)定前面必須有名字,有些則不允許有名字,也有一些偽指令的名字是任選的。即不同的偽指令對(duì)于是否有名字有不同的規(guī)定。偽指令語(yǔ)句的名字后面通常不跟冒號(hào),這是它和標(biāo)號(hào)的一個(gè)明顯區(qū)別。很多情況下偽指令語(yǔ)句中的名字是變量名。變量名代表存儲(chǔ)器中一個(gè)數(shù)據(jù)區(qū)的名字。例如,例5.1中的DATA1、DATA2就是變量名。第22頁(yè)/共274頁(yè)名字項(xiàng)用一個(gè)符號(hào)表示。
對(duì)符號(hào)的規(guī)定:①
由字符A-Z,a-z,0-9及符號(hào)@、$、下劃線_等組成,最長(zhǎng)31個(gè)字符,超出部分忽略。②不能用數(shù)字打頭,以免與十六進(jìn)制數(shù)相混。③不使用匯編程序中的保留字(如指令的助記符等)。④對(duì)定義的符號(hào)不區(qū)分大小寫(xiě)。第23頁(yè)/共274頁(yè)
變量也有三種屬性:段、偏移量和類型。①變量的段屬性是變量所代表的數(shù)據(jù)區(qū)所在段的段地址。由于數(shù)據(jù)區(qū)一般在存儲(chǔ)器的數(shù)據(jù)段中,因此變量的段地址常常在DS和ES寄存器中。②變量的偏移量屬性是該變量所在段的起始地址與變量的地址之間的字節(jié)數(shù)。③變量的類型屬性有BYTE(字節(jié))、WORD(字)、DWORD(雙字)、QWORD(四字)、TBYTE(十字)等,表示數(shù)據(jù)區(qū)中存取操作對(duì)象的大小。第24頁(yè)/共274頁(yè)2)助記符匯編語(yǔ)言語(yǔ)句中的第二個(gè)組成部分是助記符(Memonic)。在指令語(yǔ)句中的第二部分是CPU指令系統(tǒng)中指令的助記符,如MOV、ADC等。助記符約有90多種,在第4章指令系統(tǒng)中已經(jīng)進(jìn)行了討論。
在偽指令語(yǔ)句中的第二部分是偽指令的定義符,如DB、SEGMENT、ENDS、END等。它們?cè)诔绦蛑械淖饔檬嵌x變量的類型、定義段以及告訴匯編程序結(jié)束匯編等。關(guān)于偽指令的作用和使用方法,將在5.3節(jié)中討論。第25頁(yè)/共274頁(yè)
助記符可以是指令、偽操作中的助記符。
①對(duì)于指令,匯編程序?qū)⑵浞g成機(jī)器語(yǔ)言指令。MOVAX,100→B80001②對(duì)于偽操作,匯編程序根據(jù)其要求的功能進(jìn)行處理。dataSEGMENT→data與一個(gè)段值相對(duì)應(yīng)stringDB‘USTB’→string與一個(gè)內(nèi)存地址相對(duì)應(yīng)。第26頁(yè)/共274頁(yè)3)操作數(shù)匯編語(yǔ)言語(yǔ)句中的第三個(gè)組成部分是操作數(shù)。操作數(shù)項(xiàng)在指令語(yǔ)句中是指令的操作數(shù),可能有單操作數(shù)或雙操作數(shù),也可能無(wú)操作數(shù);操作數(shù)給出參與操作的數(shù)或數(shù)所在的地方。在偽指令中可能有更多個(gè)操作數(shù)。操作數(shù)多于一個(gè)時(shí),用逗號(hào)分開(kāi)。操作數(shù)可以是常數(shù)、寄存器、存儲(chǔ)器操作數(shù)、標(biāo)號(hào)名、過(guò)程名或表達(dá)式等。
第27頁(yè)/共274頁(yè)(1)常數(shù)。常數(shù)就是指令中出現(xiàn)的那些固定值,可以分為數(shù)值常數(shù)和字符串常數(shù)兩類。例如,立即數(shù)尋址時(shí)所有的立即數(shù)、直接尋址時(shí)所有的地址、ASCII字符串等都是常數(shù)。常數(shù)是除了自身的值以外,沒(méi)有其他屬性的數(shù)值。在源程序中,數(shù)值常數(shù)按其基數(shù)的不同,可有二進(jìn)制數(shù)、八進(jìn)制數(shù)、十進(jìn)制數(shù)、十六進(jìn)制數(shù)等幾種不同表示形式。匯編語(yǔ)言用不同的后綴加以區(qū)別(如B,H等)。第28頁(yè)/共274頁(yè)常數(shù):給出具體的數(shù)據(jù)??梢允菙?shù)字常量或字符常量。◢◢
數(shù)字默認(rèn)十進(jìn)制,也可加D表示十進(jìn)制數(shù)。如
1234D,1234◢
◢
數(shù)字后加B表示二進(jìn)制數(shù)。如
1010B◢
◢
數(shù)字后加H表示十六進(jìn)制數(shù)。如1234H◢
◢
字符常量,用單引號(hào)表示。如‘1234’
匯編時(shí),用字符對(duì)應(yīng)的ASCII表示。如
31H,32H,33H,34H例
data1DB12,34,56;十進(jìn)制
data2DB12H,34H,56H;十六進(jìn)制
MOVAL,‘G’;字符
stringDB‘1234’;字符串第29頁(yè)/共274頁(yè)
A、B、C、D、E、F開(kāi)頭的十六進(jìn)制數(shù)前面加0,與H結(jié)尾的標(biāo)識(shí)符區(qū)別。如寄存器名AH、BH、CH、
DH
變量名abcdH等例
movAL,0AHmovAL,AHmovBX,0abcdH第30頁(yè)/共274頁(yè)
匯編語(yǔ)言中的數(shù)值常數(shù)的第一位必須是數(shù)字,否則匯編時(shí)將被看成是標(biāo)識(shí)符,如常數(shù)B7H應(yīng)寫(xiě)成0B7H,F(xiàn)FH應(yīng)寫(xiě)成0FFH。字符串常數(shù)是由單引號(hào)括起來(lái)的一串字符。例.‘ABCDEFG’和‘179’。單引號(hào)內(nèi)的字符在匯編時(shí)都以ASCII的代碼形式存放在存儲(chǔ)單元中。如上述兩字符串的ASCII代碼為41H,42H,43H,44H,…,48H和31H,37H,39H。字符串最長(zhǎng)允許有255個(gè)字符。第31頁(yè)/共274頁(yè)(2)寄存器。8086/8088CPU的寄存器可以作為指令的操作數(shù)。
(3)標(biāo)號(hào)。由于標(biāo)號(hào)代表一條指令的符號(hào)地址,因此可以作為轉(zhuǎn)移(無(wú)條件轉(zhuǎn)移或條件轉(zhuǎn)移)、過(guò)程調(diào)用CALL以及循環(huán)控制LOOP指令的操作數(shù)。
(4)變量。因?yàn)樽兞渴谴鎯?chǔ)器中某個(gè)數(shù)據(jù)區(qū)的名字,所以在指令中可以作為存儲(chǔ)器操作數(shù)。第32頁(yè)/共274頁(yè)(5)表達(dá)式。匯編語(yǔ)言語(yǔ)句中的表達(dá)式,按其性質(zhì)可分為兩種:數(shù)值表達(dá)式和地址表達(dá)式。數(shù)值表達(dá)式產(chǎn)生一個(gè)數(shù)值結(jié)果,只有大小,沒(méi)有屬性。地址表達(dá)式的結(jié)果不是一個(gè)單純的數(shù)值,而是一個(gè)表示存儲(chǔ)器地址的變量或標(biāo)號(hào),它有三種屬性:段、偏移量和類型。第33頁(yè)/共274頁(yè)
表達(dá)式中常用的運(yùn)算符有以下幾種:①算術(shù)運(yùn)算符。常用的算術(shù)運(yùn)算符有:+(加),?(減),*(乘),/(除)和MOD(模除,即兩個(gè)整數(shù)相除后取余數(shù))等。以上算術(shù)運(yùn)算符可用于數(shù)值表達(dá)式,運(yùn)算結(jié)果是一個(gè)數(shù)值。在地址表達(dá)式中通常只使用其中的+和-(加和減)兩種運(yùn)算符。第34頁(yè)/共274頁(yè)②邏輯運(yùn)算符。邏輯運(yùn)算符有:AND(邏輯“與”),OR(邏輯“或”),XOR(邏輯“異或”)和NOT(邏輯“非”)。邏輯運(yùn)算符只用于數(shù)值表達(dá)式中對(duì)數(shù)值進(jìn)行按位邏輯運(yùn)算,并得到一個(gè)數(shù)值結(jié)果。對(duì)地址進(jìn)行邏輯運(yùn)算是沒(méi)有意義的。第35頁(yè)/共274頁(yè)③關(guān)系運(yùn)算符。關(guān)系運(yùn)算符有:EQ(等于),NE(不等),LT(小于),GT(大于),LE(小于或等于),GE(大于或等于)等。參與關(guān)系運(yùn)算的必須是兩個(gè)數(shù)值或同一段中的兩個(gè)存儲(chǔ)單元地址,但運(yùn)算結(jié)果只可能是兩個(gè)特定的數(shù)值之一:當(dāng)關(guān)系不成立(假)時(shí),結(jié)果為0(全0);當(dāng)關(guān)系成立(真)時(shí),結(jié)果為0FFFFH(全1)。例如:
MOVAX,4EQ3 ;關(guān)系不成立,故(AX)←0MOVAX,4NE3 ;關(guān)系成立,故(AX)←0FFFFH第36頁(yè)/共274頁(yè)④分析運(yùn)算符分析運(yùn)算符用于分析一個(gè)存儲(chǔ)器操作數(shù)的屬性,如段值、偏移量和類型等,或取得它所定義的存儲(chǔ)空間的大小。分析運(yùn)算符有SEG、OFFSET、TYPE、SIZE和LENGTH等。●SEG運(yùn)算符。利用SEG運(yùn)算符可以得到一個(gè)標(biāo)號(hào)或變量所在段的段地址。例如,下面兩條指令將變量ARRAY的段地址送DS寄存器。
MOVAX,SEGARRAYMOVDS,AX第37頁(yè)/共274頁(yè)●OFFSET運(yùn)算符利用OFFSET運(yùn)算符可以得到一個(gè)標(biāo)號(hào)或變量的偏移地址。例如:
MOVDI,OFFSETDATA1
指令執(zhí)行時(shí),將DATA1的偏移地址送到DI寄存器●
TYPE運(yùn)算符
TYPE運(yùn)算符的運(yùn)算結(jié)果是一個(gè)數(shù)值,這個(gè)數(shù)值與存儲(chǔ)器操作數(shù)類型屬性的對(duì)應(yīng)關(guān)系見(jiàn)表5.1。
第38頁(yè)/共274頁(yè)第39頁(yè)/共274頁(yè)
下面是使用TYPE運(yùn)算符的例子:
VAR DW ? ;變量VAR的類型為字
ARRAYDD 10DUP(?) ;變量ARRAY的類型為雙字
STR DB 'THISISTEST' ;變量STR的類型為字節(jié)
MOV AX,TYPEVAR ;(AX)←2MOV BX,TYPEARRAY ;(BX)←4MOV CX,TYPESTR ;(CX)←1……第40頁(yè)/共274頁(yè)●LENGTH運(yùn)算符如果一個(gè)變量已用重復(fù)操作符DUP說(shuō)明其變量的個(gè)數(shù),則利用LENGTH運(yùn)算符可得到這個(gè)變量的個(gè)數(shù)。如果未用DUP說(shuō)明,則得到的結(jié)果總是1。例如,上面的例子中已經(jīng)用“10DUP(?)”說(shuō)明變量ARRAY的個(gè)數(shù),則LENGTHARRAY的結(jié)果為10。第41頁(yè)/共274頁(yè)●SIZE運(yùn)算符如果一個(gè)變量已用重復(fù)操作符DUP說(shuō)明,則利用SIZE運(yùn)算符可得到分配給該變量的字節(jié)總數(shù)。如果未用DUP說(shuō)明,則得到的結(jié)果是TYPE運(yùn)算的結(jié)果。例如,上面的例子中變量ARRAY的個(gè)數(shù)為10,類型為DWORD(雙字),因此,SIZEARRAY的結(jié)果為10×4=40。由此可知,SIZE的運(yùn)算結(jié)果等于LENGTH的運(yùn)算結(jié)果乘以TYPE的運(yùn)算結(jié)果。第42頁(yè)/共274頁(yè)⑤合成運(yùn)算符。合成運(yùn)算符可以用來(lái)建立或臨時(shí)改變變量或標(biāo)號(hào)的類型或存儲(chǔ)器操作數(shù)的存儲(chǔ)單元類型。合成運(yùn)算符有PTR、THIS、SHORT等?!馪TR運(yùn)算符。PTR運(yùn)算符可以指定或修改存儲(chǔ)器操作數(shù)的類型,例如:
INC BYTEPTR[BX][SI]
指令中利用PTR運(yùn)算符明確規(guī)定了存儲(chǔ)器操作數(shù)的類型是BYTE(字節(jié)),因此,本指令將一個(gè)字節(jié)型存儲(chǔ)器操作數(shù)加1。第43頁(yè)/共274頁(yè)
利用PTR運(yùn)算符可以建立一個(gè)新的存儲(chǔ)器操作數(shù),它與原來(lái)的同名操作數(shù)具有相同的段和偏移量,但可以有不同的類型。不過(guò)這個(gè)新類型只在當(dāng)前語(yǔ)句中有效。例如:
STUFFDD? ;定義STUFF為雙字類型變量
MOVBX,WORDPTRSTUFF;從STUFF中取一個(gè)字到BX……第44頁(yè)/共274頁(yè)●THIS運(yùn)算符。THIS運(yùn)算符也可指定存儲(chǔ)器操作數(shù)的類型。使用THIS運(yùn)算符可以使標(biāo)號(hào)或變量更具靈活性。例如,要求對(duì)同一個(gè)數(shù)據(jù)區(qū)既可以字節(jié)為單位,又可以字為單位進(jìn)行存取,則可用以下語(yǔ)句:
TAB1EQUTHISWORD TAB2DB100DUP(?)
上面TAB1和TAB2實(shí)際上代表同一個(gè)數(shù)據(jù)區(qū),其中共有100個(gè)字節(jié),但TAB1的類型為WORD(字類型),而TAB2的類型為BYTE(字節(jié)類型)。第45頁(yè)/共274頁(yè)●?SHORT運(yùn)算符。SHORT運(yùn)算符指定一個(gè)標(biāo)號(hào)的類型為SHORT(短標(biāo)號(hào)),即標(biāo)號(hào)到引用該標(biāo)號(hào)指令之間的距離在?128~+127個(gè)字節(jié)的范圍內(nèi)。短標(biāo)號(hào)可以被用于無(wú)條件轉(zhuǎn)移指令中。使用短標(biāo)號(hào)的指令比使用缺省的近標(biāo)號(hào)的指令少一個(gè)字節(jié)。第46頁(yè)/共274頁(yè)⑥其他運(yùn)算符?!穸纬竭\(yùn)算符“:”。運(yùn)算符“:”(冒號(hào))跟在段寄存器名(DS,ES,SS和CS)之后,表示段超越,用以給一個(gè)存儲(chǔ)器操作數(shù)指定一個(gè)段屬性,而不管其原來(lái)隱含的段是什么。例如:
MOVAX,ES:[DI]第47頁(yè)/共274頁(yè)●字節(jié)分離運(yùn)算符LOW和HIGH。運(yùn)算符LOW和HIGH分別得到一個(gè)數(shù)值或地址表達(dá)式的低位和高位字節(jié)。例如:
STUFFEQU 0ABCDH MOV AH,HIGHSTUFF ;(AH)←0ABHMOV AL,LOWSTUFF ;(AL)←0CDH第48頁(yè)/共274頁(yè)
以上介紹了表達(dá)式中使用的各種運(yùn)算符,如果一個(gè)表達(dá)式同時(shí)具有多個(gè)運(yùn)算符,則按以下規(guī)則運(yùn)算:①優(yōu)先級(jí)高的先運(yùn)算,優(yōu)先級(jí)低的后運(yùn)算。②優(yōu)先級(jí)相同時(shí)按表達(dá)式中從左到右的順序運(yùn)算。③括號(hào)可以提高運(yùn)算的優(yōu)先級(jí),括號(hào)內(nèi)的運(yùn)算總是在相鄰的運(yùn)算之前進(jìn)行。第49頁(yè)/共274頁(yè)表5.2運(yùn)算符的優(yōu)先級(jí)
第50頁(yè)/共274頁(yè)4)注釋
匯編語(yǔ)言語(yǔ)句的最后一個(gè)組成部分是注釋。對(duì)于一個(gè)匯編語(yǔ)言語(yǔ)句來(lái)說(shuō),注釋部分并不是必要的,但是加上適當(dāng)?shù)淖⑨屢院?,可以增加源程序的可讀性。一個(gè)較長(zhǎng)的實(shí)用程序,如果從頭到尾沒(méi)有任何注釋,可能很難讀懂。因此,最好在重要的程序段前面以及關(guān)鍵處加上簡(jiǎn)明扼要的注釋。注釋前面要求加上分號(hào)(;)。如果注釋的內(nèi)容較多,超過(guò)一行,則換行以后前面還要加上分號(hào)。注釋也可以從一行的最前面開(kāi)始,以表示對(duì)一個(gè)程序段的說(shuō)明。匯編程序?qū)τ谧⑨尣挥枥頃?huì),即注釋對(duì)匯編后產(chǎn)生的目標(biāo)程序沒(méi)有任何影響。第51頁(yè)/共274頁(yè)5.3偽指令語(yǔ)句
偽指令無(wú)論表示形式或其在語(yǔ)句中所處的位置,都與指令相似。但二者之間有著重要的區(qū)別。首先,指令是給CPU的命令,在運(yùn)行時(shí)由CPU執(zhí)行,每條指令對(duì)應(yīng)CPU的一種特定的操作,例如傳送、加法等;而偽指令是給匯編程序的命令,在匯編過(guò)程中由匯編程序進(jìn)行處理,例如定義數(shù)據(jù)、分配存儲(chǔ)區(qū)、定義段以及定義過(guò)程等。其次,匯編以后,每條指令產(chǎn)生一一對(duì)應(yīng)的目標(biāo)代碼;而偽指令則不產(chǎn)生與之相應(yīng)的目標(biāo)代碼。宏匯編程序MASM提供了幾十種偽指令,其中有一些偽指令小匯編ASM不能支持,如宏處理其等。根據(jù)其功能,偽指令大致可以分為以下幾類:第52頁(yè)/共274頁(yè)●數(shù)據(jù)定義偽指令●符號(hào)定義偽指令●段定義偽指令●過(guò)程定義偽指令●宏處理偽指令●模塊定義與連接偽指令●處理器選擇偽指令●條件偽指令●列表偽指令
●其他偽指令第53頁(yè)/共274頁(yè)5.3.1數(shù)據(jù)定義偽指令數(shù)據(jù)定義偽指令的用途是定義一個(gè)變量的類型,給變量賦初值,或者僅僅給變量分配存儲(chǔ)單元,而不賦予特定的值。數(shù)據(jù)定義偽指令有DB,DW,DD,DF,DQ,DT等,而常用的是前三種。數(shù)據(jù)定義偽指令的一般格式為:
[變量名]偽指令定義符操作數(shù)[,操作數(shù)…]其中方括號(hào)中的變量名為任選項(xiàng),可以有,也可以沒(méi)有。變量名后面不跟冒號(hào)。偽指令定義符后面的操作數(shù)可以不止一個(gè)。如有多個(gè)操作數(shù),相互之間應(yīng)該用逗號(hào)分開(kāi)。第54頁(yè)/共274頁(yè)1.DB(DefineByte)
定義變量的類型為字節(jié)(BYTE),給變量分配字節(jié)或字節(jié)串。DB偽指令定義符后面的操作數(shù)每個(gè)占有1個(gè)字節(jié)。
2.DW(DefineWord)
定義變量的類型為字(WORD)。DW偽指令定義符后面的操作數(shù)每個(gè)占有1個(gè)字,即2個(gè)字節(jié)。在內(nèi)存中存放時(shí),低位字在前,高位字在后。第55頁(yè)/共274頁(yè)3.DD(DefineDoubleword)
定義變量的類型為雙字(DWORD)。DD后面的操作數(shù)每個(gè)占有2個(gè)字,即4個(gè)字節(jié)。在內(nèi)存中存放時(shí),低位字在前,高位字在后。數(shù)據(jù)定義偽指令定義符后面的操作數(shù)可以是常數(shù)、表達(dá)式或字符串,但每項(xiàng)操作數(shù)的值不能超過(guò)由偽指令定義符所定義的數(shù)據(jù)類型限定的范圍。例如,DB偽指令定義數(shù)據(jù)的類型為字節(jié),則其范圍為無(wú)符號(hào)數(shù):0~255;帶符號(hào)數(shù):?128~+127,等等。字符串必須放在單引號(hào)中。另外,超過(guò)兩個(gè)字符的字符串只能用DB偽指令定義。請(qǐng)看下列語(yǔ)句:第56頁(yè)/共274頁(yè)DATA DB 101,0F0H ;存入65H,F(xiàn)0HEXPR DB 2*8+7;存入17HSTR DB 'WELCOME!' ;存入8個(gè)字符的ASCII碼值A(chǔ)B DB 'AB';存入41H,42HBA DW 'AB';存入42H,41HABDD DD 'AB' ;存入42H,41H,00,00OFFAB DW AB ;存入變量AB的偏移地址ADRS DW STR,STR+3,STR+5 ;存入3個(gè)偏移地址
TOTAL DD DATA;先存DATA的偏移地址,再存段地址第57頁(yè)/共274頁(yè)
以上第一和第二句中,分別將常數(shù)和表達(dá)式的值賦予一個(gè)變量。第三句的操作數(shù)是包含8個(gè)字符的字符串(只有DB偽指令才能用)。在第四、五、六句,注意偽指令DB、DW和DD的區(qū)別,雖然操作數(shù)均為'AB'兩個(gè)字符,但存入變量的內(nèi)容各不相同。第七句的操作數(shù)是變量AB,而不是字符串,此句將AB的16位偏移地址存入變量OFFAB。第八句存入三個(gè)等距的偏移地址,共占6字節(jié)。第九句中的DD偽指令定義符將DATA的偏移地址和段地址順序存入變量TOTAL,共占2個(gè)字。第58頁(yè)/共274頁(yè)
除了常數(shù)、表達(dá)式和字符串外,問(wèn)號(hào)“?”也可以作為數(shù)據(jù)定義偽指令的操作數(shù),此時(shí)僅給變量保留相應(yīng)的存儲(chǔ)單元,而不賦予變量某個(gè)確定的初值。當(dāng)同樣的操作數(shù)重復(fù)多次時(shí),可用重復(fù)操作符“DUP”表示,其形式為:
nDUP(初值[,初值,…])其中圓括號(hào)中為重復(fù)的內(nèi)容,n為重復(fù)次數(shù)。如果用“nDUP(?)”作為數(shù)據(jù)定義偽指令定義符的惟一操作數(shù),則匯編程序產(chǎn)生一個(gè)相應(yīng)的數(shù)據(jù)區(qū),但不賦任何初值。重復(fù)操作符“DUP”可以嵌套。下面是用問(wèn)號(hào)或“DUP”表示操作數(shù)的幾個(gè)例子:第59頁(yè)/共274頁(yè)FILLER DB ?SUM DW ? DB ?,?,? BUFFER DB 10DUP(?)ZERO DW 30DUP(0)MASK DB5DUP('OK!')ARRAY DB 100DUP(3DUP(8),6)第60頁(yè)/共274頁(yè)其中第一、第二句分別給字節(jié)變量FILLER和字變量SUM分配存儲(chǔ)單元,但不賦予特定的值。第三句給一個(gè)沒(méi)有名稱的字節(jié)變量賦予3個(gè)不確定的值。第四句給變量BUFFER分配10個(gè)字節(jié)的存儲(chǔ)空間,但不賦任何初值。第五句給變量ZERO分配一個(gè)數(shù)據(jù)區(qū),共30個(gè)字(即60字節(jié)),每個(gè)字的內(nèi)容均為零。第六句定義一個(gè)數(shù)據(jù)區(qū),其中有5個(gè)重復(fù)的字符串'OK!',共占15字節(jié)。最后一句將變量ARRAY定義為一個(gè)數(shù)據(jù)區(qū),其中包含重復(fù)100次的內(nèi)容:8,8,8,6,共占400個(gè)字節(jié)。第61頁(yè)/共274頁(yè)
通常把用DUP作為惟一操作數(shù)而定義的變量稱為數(shù)組。下面是幾個(gè)錯(cuò)誤的數(shù)據(jù)定義偽指令語(yǔ)句:
ERROR1:DW99 ;變量名后有冒號(hào)
ERROR2DB25*90 ;DB的操作數(shù)超過(guò)255 ERROR3DD‘1234’ ;DD的操作數(shù)是超過(guò)2個(gè)字 符的字符串第62頁(yè)/共274頁(yè)5.3.2符號(hào)定義偽指令符號(hào)定義偽指令的用途是給一個(gè)符號(hào)重新命名,或定義新的類型屬性等。符號(hào)包括匯編語(yǔ)言的變量名、標(biāo)號(hào)名、過(guò)程名、寄存器名以及指令助記符等。常用的符號(hào)定義偽指令有EQU、=(等號(hào))和LABLE。第63頁(yè)/共274頁(yè)
1.EQU
格式:名字EQU表達(dá)式
EQU偽指令將表達(dá)式的值賦予一個(gè)名字。以后可用這個(gè)名字來(lái)代替上述表達(dá)式。格式中的表達(dá)式可以是一個(gè)常數(shù)、符號(hào)、數(shù)值表達(dá)式或地址表達(dá)式等。例如: CR EQU 0DH ;常數(shù)
LF EQU 0AH A EQU ASCII_TABLE ;變量第64頁(yè)/共274頁(yè) STR EQU 64*1024 ;數(shù)值表達(dá)式
ADREQU ES:[BP+DI+5] ;地址表達(dá)式
CBDEQU AAM ;指令助記符
利用EQU偽指令,可以用一個(gè)名字代表一個(gè)數(shù)值,或用一個(gè)較簡(jiǎn)短的名字來(lái)代替一個(gè)較長(zhǎng)的名字。如果源程序中需要多次引用某一表達(dá)式,則可以利用EQU偽指令定義符給其賦一個(gè)名字,以代替程序中的表達(dá)式,從而使程序更加簡(jiǎn)潔,便于閱讀。將來(lái)如果改變表達(dá)式的值,也只需修改一處,使程序易于維護(hù)。需要注意一個(gè)問(wèn)題:EQU偽指令不允許對(duì)同一符號(hào)重復(fù)定義。第65頁(yè)/共274頁(yè)2.=(等號(hào))
格式: 名字=表達(dá)式
=(等號(hào))偽指令的功能與EQU偽指令基本相同,主要區(qū)別在于它可以對(duì)同一個(gè)名字重復(fù)定義。例如:COUNT=100MOV CX,COUNT ;(CX)←100
COUNT?=?COUNT?10MOV BX,COUNT ;(BX)←90
……第66頁(yè)/共274頁(yè)3.LABLE
格式: 名字LABLE類型
LABLE偽指令的用途是定義標(biāo)號(hào)或變量的類型。變量的類型可以是BYTE、WORD、DWORD等;標(biāo)號(hào)的類型可以是NEAR或FAR。利用LABEL偽指令可以使同一個(gè)數(shù)據(jù)區(qū)兼有BYTE和WORD兩種屬性,這樣,在以后的程序中可根據(jù)不同的需要分別以字節(jié)或字為單位存取其中的數(shù)據(jù)。例如:第67頁(yè)/共274頁(yè)AREAWLABELWORD ;變量AREAW的類型為WORDAREABDB 100DUP(?) ;變量AREAB的類型為BYTE
MOV AREAW,AX ;AX送第1和第2字節(jié)中
MOV AREAB[49],AL ;AL送第50字節(jié)中……第68頁(yè)/共274頁(yè)LABEL偽指令也可以將一個(gè)屬性已經(jīng)定義為NEAR或者后面跟有冒號(hào)(隱含屬性為NEAR)?的標(biāo)號(hào)再定義為FAR。例如:
AGAINF LABELFAR ;定義標(biāo)號(hào)AGAINF的屬性為FAR AGAIN: PUSHAX ;定義標(biāo)號(hào)AGAIN的屬性為NEAR
上面的過(guò)程既可以利用標(biāo)號(hào)AGAIN在本段內(nèi)被調(diào)用,也可以利用標(biāo)號(hào)AGAINF被其他段調(diào)用。第69頁(yè)/共274頁(yè)5.3.3段定義偽指令段定義偽指令的用途是在匯編語(yǔ)言源程序中定義邏輯段。常用的段定義偽指令有SEGMENT/ENDS和ASSUME等。1.SEGMENT/ENDS
格式: 段名SEGMENT[定位類型][組合類型]['類別']
段名ENDS…第70頁(yè)/共274頁(yè)SEGMENT偽指令用于定義一個(gè)邏輯段,給邏輯段賦予一個(gè)段名,并以后面的任選項(xiàng)(定位類型、組合類型、‘類別’?)規(guī)定該邏輯段的其他特性。
SEGMENT偽指令位于一個(gè)邏輯段的開(kāi)始部分,而ENDS偽指令則表示一個(gè)邏輯段的結(jié)束。在匯編語(yǔ)言源程序中,這兩個(gè)偽指令定義符總是成對(duì)出現(xiàn)的,二者前面的段名必須一致。兩個(gè)語(yǔ)句之間的部分即是該邏輯段的內(nèi)容。例:對(duì)于代碼段,其中主要有指令及其他偽指令;對(duì)于數(shù)據(jù)段和附加段,主要有定義數(shù)據(jù)區(qū)的偽指令等等。一個(gè)源程序中不同邏輯段的段名可以各不相同。第71頁(yè)/共274頁(yè)SEGMENT偽指令后面還有三個(gè)任選項(xiàng):定位類型、組合類型和‘類別’。在上面的格式中,它們都放在方括號(hào)內(nèi),表示可有可無(wú)。如果有,三者的順序必須符合格式中的規(guī)定。
SEGMENT偽指令后面的這些任選項(xiàng)是給匯編程序(MASM)和連接程序(LINK)的命令。任選項(xiàng)告訴匯編程序和連接程序,如何確定段的邊界,以及如何組合幾個(gè)不同的段等。下面分別進(jìn)行討論。第72頁(yè)/共274頁(yè)1)定位(Align)類型定位類型任選項(xiàng)告訴匯編程序如何確定邏輯段的邊界在存儲(chǔ)器中的位置。定位類型共有以下四種:●BYTE(邊界起始地址=××××××××××××××××B)
該類型表示邏輯段從一個(gè)字節(jié)的邊界開(kāi)始,即可以從任何地址開(kāi)始。此時(shí)本段的起始地址可緊接在前一個(gè)段的后面。第73頁(yè)/共274頁(yè)●WORD(邊界起始地址=×××××××××××××××0B)
該類型表示邏輯段從字的邊界開(kāi)始。2字節(jié)為1個(gè)字,此時(shí)本段的起始地址必須是偶數(shù)。例:邊界起始地址的十六進(jìn)制表示可以是
×××0H或×××2H或×××4H或×××8H●PARA(邊界起始地址=××××××××××××0000B)
該類型表示邏輯段從一個(gè)節(jié)(Paragraph)的邊界開(kāi)始(一節(jié)等于16個(gè)字節(jié)),也即段的起始地址能被16整除,故本段的起始地址(十六進(jìn)制)應(yīng)為×××0H。如果省略定位類型任選項(xiàng),則默認(rèn)其為PARA。第74頁(yè)/共274頁(yè)●PAGE(邊界起始地址=××××××××00000000B)
該類型表示邏輯段從頁(yè)邊界開(kāi)始(一頁(yè)等于256個(gè)字節(jié)),也即段的起始地址能被256整除,故本段的起始地址(十六進(jìn)制)應(yīng)為××00H?!?(地址計(jì)數(shù)器偽指令)
在匯編語(yǔ)言程序內(nèi),為了指示下一個(gè)數(shù)據(jù)或指令在相應(yīng)段中的偏移量,匯編程序使用了一個(gè)當(dāng)前位置計(jì)數(shù)器$。例.STR1DW’AB’STR2DB16DUP(?)CNTEQU$-STR1MOVCX,CNT
指令執(zhí)行后,CNT=$-STR1=2+16=18=12H,所以(CX)=12H第75頁(yè)/共274頁(yè)例5.2SEGMENT偽指令定義符的定位類型應(yīng)用舉例。STACKSEGMENTSTACK;STACK段,定位類型缺省
DB100DUP(?) ;長(zhǎng)度為100字節(jié)STACKENDS ;STACK段結(jié)束DATA1SEGMENTBYTE ;DATA1段,定位類型BYTESTRINGDB'Thisisanexample!';長(zhǎng)度為19字節(jié)DATA1ENDS ;DTAT1段結(jié)束DATA2SEGMENTWORD;DATA2段,定位類型WORDBUFFERDW40DUP(0);長(zhǎng)度為40個(gè)字(80字節(jié))DATA2ENDS ;DATA2段結(jié)束第76頁(yè)/共274頁(yè)CODE1SEGMENTPAGE;CODE1段,定位類型PAGE
;假設(shè)CODE2段長(zhǎng)度為13字節(jié)CODE1ENDS;CODE1段結(jié)束CODE2SEGMENT;CODE2段,定位類型缺省
START:MOVAX,STACK;建立堆棧段
MOVSS,AX
;假設(shè)CODE2段長(zhǎng)度為52字節(jié)CODE2ENDS ;CODE2段結(jié)束
ENDSTART;源程序結(jié)束第77頁(yè)/共274頁(yè)
本例的源程序中共有五個(gè)邏輯段,它們的段名、定位類型和已知條件分別如下:
STACK段PARASTACK段的長(zhǎng)度為100字節(jié)(64H) DATA1段BYTEDATA1段的長(zhǎng)度為19字節(jié)(13H) DATA2段WORDDATA2段的長(zhǎng)度為40個(gè)字
CODE1段PAGECODE1段占用13字節(jié)(0DH) CODE2段PARACODE2段占用52字節(jié)(34H)
已經(jīng)知道其中STACK段的長(zhǎng)度為100字節(jié)(64H),DATA1段的長(zhǎng)度為19字節(jié)(13H),DATA2段的長(zhǎng)度為40個(gè)字,即80字節(jié)(50H)。假設(shè)CODE1段占用13字節(jié)(0DH),CODE2段占用52字節(jié)(34H)。如果將以上邏輯段進(jìn)行匯編和連接,然后再來(lái)觀察各邏輯段的目標(biāo)代碼或數(shù)據(jù)裝入存儲(chǔ)器的情況,如表5.3。第78頁(yè)/共274頁(yè)表5.3例5.2各邏輯段的起始地址和結(jié)束地址
段名定位類型字節(jié)數(shù)起始地址結(jié)束地址STACKPARA100(64H)00000H00063HDATA1BYTE19(13H)00064H00076HDATA2WORD80(50H)00078H000C7HCODE1PAGE13(0DH)00100H0010CHCODE2PARA52(34H)00110H00143H
由表可清楚地看出,當(dāng)SEGMENT偽指令的定位類型不同時(shí),對(duì)段起始邊界的規(guī)定也不相同。第79頁(yè)/共274頁(yè)
aaSEGMENT;數(shù)據(jù)段1
str1DB'Hello!’aaENDSbbSEGMENT;數(shù)據(jù)段2
str2DB6dup(?)bbENDSccSEGMENT;代碼段
ASSUMECS:ccASSUMEDS:aa,ES:bbstart:CLDMOVAX,aa
MOVDS,AXLEASI,str1MOVAX,bb
MOVES,AXLEADI,str2MOVCX,6REPMOVSBMOVAH,4CHINT21HccENDSENDstart
D:\masm>DEBUGhello2.exe-U:查看代碼段12A0:0000FCCLD12A0:0001B89E12MOVAX,129E12A0:00048ED8MOVDS,AX12A0:00068D360000LEASI,[0000]12A0:000AB89F12MOVAX,129F12A0:000D8EC0MOVES,AX12A0:000F8D3E0000LEADI,[0000]12A0:0013B90600MOVCX,000612A0:0016F3REPZ12A0:0017A4MOVSB12A0:0018B44CMOVAH,4C12A0:001ACD21INT21、、、-D129E:0L10;查看數(shù)據(jù)段1的內(nèi)容129E:000048656C6C6F210000-0000000000000000Hello!-D129F:0L10;查看數(shù)據(jù)段2的內(nèi)容129F:00000000000000000000-0000000000000000
-數(shù)據(jù)傳送源程序:程序經(jīng)匯編、連接后,裝入內(nèi)存的情況如下:第80頁(yè)/共274頁(yè)2)組合(Combine)類型
SEGMENT偽指令的第二個(gè)任選項(xiàng)是組合類型,它告訴匯編程序當(dāng)裝入存儲(chǔ)器時(shí)各個(gè)邏輯段如何進(jìn)行組合。組合類型共有以下六種。
(1)不組合如果SEGMENT偽指令的組合類型任選項(xiàng)缺省,則匯編程序認(rèn)為這個(gè)邏輯段是不組合的。也就是說(shuō),不同程序中的邏輯段,即使具有相同的段名,也分別作為不同的邏輯段裝入內(nèi)存,不進(jìn)行組合。但是,對(duì)于組合類型任選項(xiàng)缺省的同名邏輯段,如果屬于同一個(gè)程序模塊,則被集中成為一個(gè)邏輯段。第81頁(yè)/共274頁(yè)(2)PUBLIC
連接時(shí),對(duì)于不同程序模塊中的邏輯段,只要具有相同的段名,就把這些段集中成為一個(gè)邏輯段裝入內(nèi)存。
(3)STACK
組合類型為STACK時(shí),其含意與PUBLIC基本一樣,即不同程序中的邏輯段,如果段名相同,則集中成為一個(gè)邏輯段。不過(guò)組合類型STACK僅限于作為堆棧區(qū)域的邏輯段使用。注意:在執(zhí)行程序(.EXE)中,堆棧指針SP設(shè)置在這個(gè)集中以后的堆棧段的(最終地址+1)處。第82頁(yè)/共274頁(yè)(4)COMMON
連接時(shí),對(duì)于不同程序中的邏輯段,如果具有相同的段名,則都從同一個(gè)地址開(kāi)始裝入,因而各個(gè)邏輯段將發(fā)生重疊。最后,連接以后段的長(zhǎng)度等于原來(lái)最長(zhǎng)的邏輯段的長(zhǎng)度,重疊部分的內(nèi)容是最后一個(gè)邏輯段的內(nèi)容。
(5)MEMORY
該類型表示當(dāng)幾個(gè)邏輯段連接時(shí),本邏輯段定位在地址最高的地方。如果被連接的邏輯段中有多個(gè)段的組合類型都是MEMORY,則匯編程序只將首先遇到的段作為MEMORY段,而其余的段均當(dāng)作COMMON段處理。
(6)AT表達(dá)式這種組合類型表示本邏輯段根據(jù)表達(dá)式的值定位段地址。例如,AT8A00H,表示本段的段地址為8A00H,則本段從存儲(chǔ)器的物理地址8A000H開(kāi)始裝入。第83頁(yè)/共274頁(yè)3)'類別'('Class')SEGMENT偽指令的第三個(gè)任選項(xiàng)是?‘類別’?,類別必須放在單引號(hào)內(nèi)。‘類別’?的作用是在連接時(shí)決定各邏輯段的裝入順序。當(dāng)幾個(gè)程序模塊進(jìn)行連接時(shí),其中具有相同類別名的邏輯段被裝入連續(xù)的內(nèi)存區(qū),類別名相同的邏輯段,按出現(xiàn)的先后順序排列。沒(méi)有類別名的邏輯段,與其他無(wú)類別名的邏輯段一起連續(xù)裝入內(nèi)存。例如,設(shè)一個(gè)主程序中有五個(gè)邏輯段,段名和類別名分別為:STK1段 'STACK'CODE1段 無(wú)DATA1段 'BUFFER' DATA2段 'TABLE' DATA3段 'BUFFER'第84頁(yè)/共274頁(yè)還有一個(gè)子程序,包括四個(gè)邏輯段,段名和類別名分別為: DATA4段 'TABLE' DATA5段 'BUFFER' STK2段 'STACK' CODE2段 無(wú)
當(dāng)將上述主程序和子程序進(jìn)行連接時(shí),兩個(gè)程序模塊中各邏輯段裝入內(nèi)存的順序見(jiàn)圖5.3。第85頁(yè)/共274頁(yè)圖5.3邏輯段按類別裝入內(nèi)存的示意圖第86頁(yè)/共274頁(yè)2.ASSUME格式:ASSUME段寄存器名:段名[,段寄存器名:段名,…]ASSUME偽指令告訴匯編程序,將某一個(gè)段寄存器設(shè)置為存放某一個(gè)邏輯段的段地址,即明確指出源程序中的邏輯段與物理段之間的關(guān)系。當(dāng)匯編程序匯編一個(gè)邏輯段時(shí),即可利用相應(yīng)的段寄存器尋址該邏輯段中的指令或數(shù)據(jù)。在一個(gè)源程序中,ASSUME偽指令定義符應(yīng)該放在可執(zhí)行程序開(kāi)始位置的前面。注意:ASSUME偽指令只是通知匯編程序有關(guān)段寄存器與邏輯段的關(guān)系,并沒(méi)有給段寄存器賦予實(shí)際的初值。例如:第87頁(yè)/共274頁(yè)CODE SEGMENT ASSUMECS:CODE,DS:DATA1,SS:STACK MOV AX,DATA1 MOV DS,AX;給DS賦值
MOV AX,STACK MOV SS,AX;給SS賦值
CODE ENDS…
第88頁(yè)/共274頁(yè)
ASSUME偽操作的作用:指示匯編程序指令中用到的標(biāo)號(hào)、過(guò)程及變量所在的段。其中:對(duì)標(biāo)號(hào)、過(guò)程必須用CS段寄存器指示
對(duì)變量可用CS、DS、ES、SS段寄存器指示若未用ASSUME語(yǔ)句指示指令中用到的標(biāo)號(hào)、過(guò)程和變量所在的段,匯編程序?qū)⒔o出錯(cuò)誤信息。
ASSUME語(yǔ)句只起指示作用,并無(wú)實(shí)際的操作。在程序中引用定義的變量做內(nèi)存操作數(shù)時(shí),需按尋址方式用傳送指令(如MOV)給相應(yīng)的段寄存器賦值。第89頁(yè)/共274頁(yè)例
用程序?qū)崿F(xiàn)1234H+5678H
dataSEGMENTvalueDW1234H,5678HresultDW?
dataENDS
codeSEGMENTASSUMECS:code,DS:data
start:MOVAX,data;給DS賦值
MOVDS,AXMOVAX,value;取數(shù)
ADDAX,value+2;兩數(shù)相加
MOVresult,AX;保存結(jié)果
MOVAH,4CH;返回DOSINT21H
codeENDS
END
start第90頁(yè)/共274頁(yè)注釋掉ASSUME語(yǔ)句,其匯編結(jié)果:
dataSEGMENTvalueDW1234H,5678HresultDW?dataENDScodeSEGMENT;ASSUMECS:code,DS:datastart:MOVAX,dataMOVDS,AXMOVAX,value
ADDAX,value+2
MOVresult,AXMOVAH,4CHINT
21HcodeENDSENDstartD:\MASM>MASMassume;Microsoft(R)MacroAssemblerVersion5.10Copyright(C)MicrosoftCorp1981,1988.Allrightsreserved.assume.ASM(8):MissingorunreachableCSassume.ASM(10):Cannotaddresswithsegmentregisterassume.ASM(11):Cannotaddresswithsegmentregisterassume.ASM(12):Cannotaddresswithsegmentregister49872+421341Bytessymbolspacefree0WarningErrors
4SevereErrorsD:\MASM>第91頁(yè)/共274頁(yè)程序中有ASSUME語(yǔ)句,經(jīng)匯編,連接和裝入內(nèi)存后的情況:dataSEGMENTvalueDW1234H,5678HresultDW?dataENDScodeSEGMENTASSUMECS:code,DS:datastart:MOVAX,data;給DS賦值
MOVDS,AXMOVAX,value;取數(shù)
ADDAX,value+2;兩數(shù)相加
MOVresult,AX;保存結(jié)果
MOVAH,4CH;返回DOSINT21HcodeENDSD:\MASM>DEBUGassume.exe-R;查看程序執(zhí)行前各寄存器AX=0000BX=0000CX=0023DX=0000SP=0000BP=0000SI=0000DI=0000DS=1295ES=1295SS=12A5CS=12A6IP=0000NVUPEIPLNZNAPONC12A6:0000B8A512MOVAX,12A5-U
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 《GB-T 40644-2021杜仲葉提取物中京尼平苷酸的檢測(cè) 高效液相色譜法》專題研究報(bào)告
- 《寵物鑒賞》課件-犬的外貌特征
- 2026年徐州幼兒師范高等專科學(xué)校單招綜合素質(zhì)考試題庫(kù)及參考答案詳解1套
- 《正常人體功能》課件-酶促反應(yīng)的特點(diǎn)及影響因素
- 《幼兒文學(xué)》課件-2.1兒歌概說(shuō)
- 噪聲檢測(cè)服務(wù)合同
- 中醫(yī)艾灸技師(初級(jí))考試試卷及答案
- 2025年涂覆材料項(xiàng)目建議書(shū)
- AIGC時(shí)代下智能家電革新構(gòu)建“智慧家庭”新篇章-海爾洗護(hù)AIGC落地的最佳實(shí)踐
- 2025年煉油、化工生產(chǎn)專用設(shè)備合作協(xié)議書(shū)
- 學(xué)堂在線 臨床中成藥應(yīng)用 章節(jié)測(cè)試答案
- 物流協(xié)會(huì)管理辦法
- 跑步健康課件圖片
- 醫(yī)用耗材管理辦法原文
- 高州市緬茄杯數(shù)學(xué)試卷
- 傳承紅色基因鑄就黨紀(jì)之魂建黨104周年七一黨課
- 詩(shī)詞大會(huì)搶答題庫(kù)及答案
- 立式油罐知識(shí)培訓(xùn)課件
- 口腔健康科普指南
- 2025年《智能客戶服務(wù)實(shí)務(wù)》課程標(biāo)準(zhǔn)
- 公司便民雨傘管理制度
評(píng)論
0/150
提交評(píng)論