- 匯編語言程序設(shè)計(jì)(第3版)
- 丁輝主編
- 241字
- 2018-12-27 19:09:06
第3章 指令系統(tǒng)
本章以8086/8088指令系統(tǒng)為基礎(chǔ),從介紹指令的基本格式,操作數(shù)的尋址方式入手,講述指令系統(tǒng)中各類指令的功能、使用方法和應(yīng)用場(chǎng)合,并根據(jù)處理器的發(fā)展歷程,講述80386和Pentium處理器新增的指令。
3.1 指令格式
計(jì)算機(jī)的指令系統(tǒng)是指微處理器所能執(zhí)行的各種指令的集合。微處理器的主要功能必須通過它的指令系統(tǒng)來實(shí)現(xiàn)。不同的微處理器有著不同的指令系統(tǒng),其中每條指令與微處理器的一種基本操作相對(duì)應(yīng),這在設(shè)計(jì)微處理器時(shí)就已確定。
8086/8088指令系統(tǒng)包括上千條指令,這里所謂的指令可分為機(jī)器指令和匯編指令。機(jī)器指令用二進(jìn)制代碼表示,便于計(jì)算機(jī)識(shí)別,但不利于用戶記憶和交流;匯編指令則用一些簡(jiǎn)單的符號(hào)來表示機(jī)器指令,以彌補(bǔ)機(jī)器指令的不足。若無特殊說明,本書此后所論及的指令均為匯編指令。
微型計(jì)算機(jī)的每一條指令通常由兩部分構(gòu)成。
1.操作碼(OP-Code)
操作碼指示計(jì)算機(jī)所要執(zhí)行的操作類型。CPU執(zhí)行指令時(shí),首先將操作碼從指令隊(duì)列送到執(zhí)行部件EU中的控制單元,經(jīng)指令譯碼器分析識(shí)別后,產(chǎn)生執(zhí)行本指令操作所需的時(shí)序控制信號(hào),控制計(jì)算機(jī)完成規(guī)定的操作。
2.操作數(shù)(Operand)
操作數(shù)指出指令執(zhí)行操作所需的數(shù)據(jù)或操作結(jié)果存放的位置。有兩個(gè)操作數(shù)的指令中一個(gè)操作數(shù)稱為源操作數(shù),另一個(gè)稱為目的操作數(shù)。源操作數(shù)和目的操作數(shù)是參加操作的兩個(gè)操作數(shù),而目的操作數(shù)又存放操作的結(jié)果,也就是說,運(yùn)算后,參加運(yùn)算的一個(gè)操作數(shù)將會(huì)丟失,但一般情況下不關(guān)心這個(gè)問題。如果以后的運(yùn)算中還會(huì)用到這個(gè)操作數(shù)的話,則應(yīng)在運(yùn)算之前將其送到其他位置。
指令的基本格式如圖3.1所示。

圖3.1 指令的基本格式
3.2 尋址方式
計(jì)算機(jī)是靠指令加工處理信息的,信息寄存在寄存器中或存儲(chǔ)在存儲(chǔ)器中,執(zhí)行指令時(shí)往往要從寄存器或存儲(chǔ)器中取出信息,加工處理后又存放到寄存器或存儲(chǔ)器中。對(duì)于一條具體的指令,如何在寄存器或存儲(chǔ)器中找到指令執(zhí)行時(shí)所需的信息,如何確定執(zhí)行結(jié)果的存放位置?這就需要了解尋址方式。尋址方式說明如何尋找操作數(shù),以及如何確定執(zhí)行結(jié)果存放位置。8086/8088指令涉及四種操作數(shù):隱含操作數(shù),立即操作數(shù),寄存器操作數(shù),以及存儲(chǔ)器操作數(shù)。由此就有對(duì)應(yīng)的4類尋址方式。
3.2.1 固定尋址(Inherent Addressing)
這種尋址方式下,操作數(shù)隱含在指令中。8086/8088的某些單操作數(shù)指令規(guī)定操作數(shù)在CPU的某個(gè)固定的寄存器中,而這個(gè)寄存器又隱含在操作碼中,例如:加法的十進(jìn)制調(diào)整指令DAA,其操作數(shù)總是固定隱含在AL中;還有的雙操作數(shù)指令,例如寄存器的入棧、出棧指令只給出一個(gè)操作數(shù),而另一個(gè)操作數(shù)被固定隱含在棧頂。
使用這種尋址方式的指令不需要計(jì)算存儲(chǔ)器的有效地址EA,執(zhí)行速度較快。
3.2.2 立即尋址(Immediate Addressing)
這種尋址方式下,操作數(shù)以常量的形式出現(xiàn)在指令中。操作數(shù)隨著指令一起進(jìn)入指令隊(duì)列,不必執(zhí)行總線周期,故稱為立即數(shù)。立即數(shù)可以為8位,也可以為16位。如果是16位數(shù),則低字節(jié)存放在低地址單元中,高字節(jié)存放在高地址單元中。立即尋址方式用來表示常數(shù),它常用于給寄存器賦初值,立即數(shù)只能用做源操作數(shù),不能用做目的操作數(shù)。
【例3.1】MOV CX,9;立即數(shù)9作為源操作數(shù)賦給寄存器CX。
【例3.2】MOV AX,5807H
指令執(zhí)行后(AX)=5807H,如圖3.2所示。圖中指令存放在代碼段中,OP表示該指令的操作碼部分,5807H則為立即數(shù),它是指令的一部分。

圖3.2 指令執(zhí)行情況
3.2.3 寄存器尋址(Register Addressing)
這種尋址方式下,操作數(shù)為通用寄存器或段寄存器(CS除外)。16位寄存器操作數(shù)可以是AX、BX、CX、DX、SI、DI、SP、BP、DS、SS及ES;8位寄存器操作數(shù)可以是AL、AH、BL、BH、CL、CH、DL和DH。這種尋址方式由于操作數(shù)就是CPU的寄存器,不需要執(zhí)行總線周期,執(zhí)行速度較快。因此,在既可使用寄存器尋址又可使用后述的存儲(chǔ)器尋址的場(chǎng)合,常常選用前者。
【例3.3】MOV AX,CX
若指令執(zhí)行前(AX)=9602H,(CX)=2081H;則指令執(zhí)行后,(AX)=2081H,(CX)內(nèi)容保持不變。指令執(zhí)行情況如圖3.3所示。

圖3.3 寄存器尋址方式執(zhí)行情況
3.2.4 存儲(chǔ)器尋址
存儲(chǔ)器尋址方式下,操作數(shù)一般是代碼段之外的數(shù)據(jù)段、堆棧段、附加數(shù)據(jù)段中的存儲(chǔ)單元,指令給出的是存儲(chǔ)單元的地址或產(chǎn)生存儲(chǔ)單元地址的表達(dá)式。執(zhí)行此類指令時(shí),CPU首先根據(jù)操作數(shù)字段提供的地址信息,由執(zhí)行部件EU計(jì)算出有效地址EA(EA是一個(gè)不帶符號(hào)的16位數(shù)據(jù),代表操作數(shù)地址離段首地址的距離,即該地址到段首地址的字節(jié)數(shù)),再由總線執(zhí)行部件BIU根據(jù)公式PA=(16×段首地址)+EA計(jì)算出操作數(shù)的物理地址。
一般而言,一條指令的目的操作數(shù)和源操作數(shù)不能同為存儲(chǔ)器操作數(shù)。存儲(chǔ)器尋址方式按EA計(jì)算方法的不同可以分為5種。
1. 直接尋址(Direct Addressing)
格式:(1)[常量]
(2)變量
直接尋址是最簡(jiǎn)單的存儲(chǔ)器尋址。這種尋址方式下,操作數(shù)的有效地址由指令直接給出,是帶有方括號(hào)的常量或是變量。
需要說明的是,該方式下,操作數(shù)的段地址默認(rèn)為在數(shù)據(jù)段寄存器DS中,即DS為默認(rèn)段寄存器。因此,直接尋址方式下,作為操作數(shù)的存儲(chǔ)單元的物理地址為:
PA=16×(DS)+nn
這里nn表示常量或變量的偏移地址。
【例3.4】MOV AL,[1000H];將DS段1000H單元的內(nèi)容傳送到AL中。
【例3.5】MOV AX,[1000H]
與上一條指令不同的是,指令執(zhí)行后將DS段中偏移地址為1000H的字單元內(nèi)容傳送到AX,即低地址1000H對(duì)應(yīng)AL,高地址1001H對(duì)應(yīng)AH。若(DS)=2000H,(21000H)=3412H,則該指令執(zhí)行后(AX)=3412H。指令執(zhí)行情況如圖3.4所示。

圖3.4 指令執(zhí)行情況
使用直接尋址方式時(shí)應(yīng)注意:
(1)直接地址可用數(shù)值表示,包括在[ ]之中,也可以用變量表示,例如:MOV AL,VALUE;這里,VALUE為變量,變量是有屬性的,它由數(shù)據(jù)段中定義數(shù)據(jù)的偽指令確定(偽指令將在第4章介紹)。
(2)若操作數(shù)在代碼段、堆棧段或附加段中,則應(yīng)在操作數(shù)地址之前使用前綴指出段寄存器名,這種前綴稱為段超越前綴。例如:
MOV AL,ES:[2000H] ;將ES段2000H單元的內(nèi)容傳送到AL中
段超越前綴也可以用于其他存儲(chǔ)器尋址方式中,以使得給定的段寄存器取代默認(rèn)的段寄存器。
(3)直接尋址方式適合于處理存儲(chǔ)器的單個(gè)單元。IBM-PC機(jī)中為了避免指令字的長(zhǎng)度過長(zhǎng),規(guī)定雙操作數(shù)指令除立即尋址方式之外必須有一個(gè)操作數(shù)使用寄存器或段寄存器,這就是一個(gè)變量常常先要送到寄存器中去的原因。
2.寄存器間接尋址(Register Indirect Addressing)
格式:[BX、BP、SI或DI]
這種尋址方式下,操作數(shù)的有效地址EA不像直接尋址那樣直接放在指令中,而是由基址寄存器BX、BP或變址寄存器SI、DI之一給出,即

如果指令中使用的是BX、SI和DI,則操作數(shù)在數(shù)據(jù)段中,且用數(shù)據(jù)段寄存器DS中的內(nèi)容作為段地址,即操作數(shù)的物理地址為

【例3.6】MOV AL,[BX];設(shè)BX的內(nèi)容為1000H,則指令功能是將DS段1000H單元的內(nèi)容傳送到AL中。
【例3.7】MOV AX,[BX]
設(shè)(DS)=2000H,(BX)=1000H,(21000H)=3412H,物理地址PA=16×2000H+1000H=20000+1000H=21000H,執(zhí)行情況如圖3.5所示。

圖3.5 寄存器間接尋址執(zhí)行情況
指令執(zhí)行后,(AX)=3412H。
若指令中使用的是BP,則操作數(shù)在堆棧段中,用堆棧段寄存器SS中的內(nèi)容作為段地址,即操作數(shù)的物理地址為
PA=16×(SS)+(BP)
寄存器間接尋址通常用來對(duì)一維數(shù)組進(jìn)行處理。只需在執(zhí)行完一條指令后改變間接尋址寄存器BX、BP、SI和DI中的內(nèi)容,就可以使用同一個(gè)地址表達(dá)式來指定一維數(shù)組中的不同元素,從而對(duì)連續(xù)的存儲(chǔ)器單元進(jìn)行存/取操作。
3. 基址尋址(Based Addressing)
格式:偏移量[BX或BP]
其中偏移量可以是常量或變量,還可以表示為[BX或BP][偏移量]和[BX或BP+偏移量]。
這種尋址方式與寄存器間接尋址方式的區(qū)別僅在于,只能使用基址寄存器BX和BP,且指令中還要指定一個(gè)8位或者16位的偏移量,操作數(shù)的有效地址EA等于基址寄存器BX或BP的內(nèi)容與偏移量之和,該偏移量在兩個(gè)字節(jié)范圍內(nèi),即

【例3.8】MOV AL,80H[BP];設(shè)BP內(nèi)容為2040H,則指令功能是將堆棧段20C0H單元的內(nèi)容傳送到AL中。
該指令又可表達(dá)為
MOV AL,[BP][80H] 或MOV AL,[BP+80H]
【例3.9】MOV AX,COUNT[BX]
設(shè)(DS)=2000H,(BX)=1000H,COUNT=3000H,(24000H)=1058H,其尋址示意圖如圖3.6所示。指令執(zhí)行后,(AX)=1058H。

圖3.6 基址尋址方式執(zhí)行情況
基址尋址通常也用來訪問一維數(shù)組中的元素,用偏移量來確定數(shù)組的起點(diǎn),基址寄存器的值選擇一個(gè)元素。與寄存器間接尋址一樣,因數(shù)組中所有元素具有相同的長(zhǎng)度,只要改變基址寄存器的內(nèi)容,就可以使用同一個(gè)地址表達(dá)式選擇數(shù)組中任意的元素。
4.變址尋址(Indexed Addressing)
格式:偏移量[SI或DI]。
其中偏移量可以是常量或變量,其他的表示形式類似于基址尋址方式,只需將基址寄存器BX、BP換成變址寄存器SI、DI即可。變址尋址中總是使用段寄存器DS的內(nèi)容作段首地址,操作數(shù)的有效地址EA等于間址寄存器內(nèi)容和位移量之和,即

變址尋址方式同樣適合處理數(shù)組,通常SI用于源數(shù)組的變址尋址,DI則用于目的數(shù)組的變址尋址。
例如: MOV AX,ARRAY1[SI] MOV ARRAY2[DI],AX
其中ARRAY1和ARRRAY2分別用來表示源數(shù)組和目的數(shù)組的起點(diǎn)。若用上述兩條指令,配上修改SI、DI值的指令,構(gòu)成循環(huán),就可實(shí)現(xiàn)將源數(shù)組移動(dòng)到目的數(shù)組的目的。
5.基址變址尋址(Based Indexed Addressing)
格式:偏移量[BX或BP+SI或DI]。
其中偏移量可以是常量或變量,其他的表示形式類似于基址尋址方式,只需將基址寄存器換成基址+變址寄存器即可。
這種尋址方式下,存儲(chǔ)器操作數(shù)的有效地址EA是指令指定的基址寄存器BX、BP之一與變址寄存器SI、DI之一的內(nèi)容以及偏移量三者之和,即

這里共有四種組合情況,并且根據(jù)基址是在BX還是在BP中,確定尋址操作數(shù)是在數(shù)據(jù)段還是堆棧段。對(duì)于前者,段寄存器使用DS;對(duì)于后者,段寄存器使用SS。基址變址尋址的操作數(shù)物理地址為

【例3.10】MOV AX,3000H[BX+SI]
設(shè)(DS)=1000H,(BX)=0400H,(SI)=1260H;
則:EA=0400H+1260H+3000H=4660H
PA=10000H+4660H=14660H
指令的執(zhí)行情況如圖3.7所示。指令執(zhí)行后,(AX)=1058H。

圖3.7 基址變址尋址方式執(zhí)行情況
應(yīng)當(dāng)注意以下指令是錯(cuò)誤的:
MOV AX,30H[BX][BP] MOV AX,10H[SI][DI]
基址變址尋址方式同樣適合數(shù)組或表格的處理,由于基址和變址寄存器中的內(nèi)容都可以改變,在處理二維數(shù)組時(shí)尤為方便。
這種尋址方式中,若偏移量為0,則偏移量可默認(rèn)。即指令
MOV AX,0[BX+SI]
可表示為
MOV AX,[BX+SI]
3.3 指令的執(zhí)行時(shí)間
通常,一條指令的執(zhí)行時(shí)間是指計(jì)算機(jī)取指令、取操作數(shù)、執(zhí)行指令及傳送結(jié)果各個(gè)階段所需時(shí)間的總和。如果要詳細(xì)討論各種指令的執(zhí)行時(shí)間是一個(gè)比較復(fù)雜的問題,這里只作簡(jiǎn)單介紹。
由于指令是存放在存儲(chǔ)器中,因此運(yùn)算器要執(zhí)行指令就需先訪問存儲(chǔ)器,但是8086/8088 CPU的執(zhí)行部件EU和總線接口部件BIU是并行工作的,BIU可以預(yù)先把指令取到指令隊(duì)列緩沖器中存放,形成了取指和執(zhí)行的并行,這樣,在計(jì)算指令的執(zhí)行時(shí)間時(shí),就不把取指時(shí)間計(jì)算在內(nèi)。
執(zhí)行指令的時(shí)間,除了EU中的基本執(zhí)行時(shí)間外,有些指令在執(zhí)行過程中可能需要多次訪問內(nèi)存,包括取操作數(shù)和存放操作數(shù)結(jié)果等,要執(zhí)行總線的讀/寫周期,這樣,執(zhí)行一條指令的時(shí)間就是指令的基本執(zhí)行時(shí)間及存取操作數(shù)時(shí)間的總和。指令的基本執(zhí)行時(shí)間因指令的不同而異,相互之間有很大的差別,而存取操作數(shù)所需的計(jì)算有效地址EA的時(shí)間又隨尋址方式的不同而異。
表3.1表示執(zhí)行幾種不同的指令所需的時(shí)間;表3.2表示執(zhí)行加法時(shí)不同的尋址方式所需的時(shí)間;表3.3表示在不同的尋址方式下計(jì)算EA所需的時(shí)間。在這些表格中,所有的時(shí)間都以時(shí)鐘周期數(shù)表示(計(jì)算機(jī)是按照節(jié)拍工作的,這里所說的節(jié)拍稱為時(shí)鐘周期)。
表3.1 指令的基本執(zhí)行時(shí)間舉例

表3.2 加法指令的執(zhí)行時(shí)間

表3.3 計(jì)算有效地址EA所需的時(shí)間

從表3.1至表3.3可以看出,不僅不同指令的執(zhí)行時(shí)間差別很大,而且同一種指令使用不同的尋址方式時(shí)執(zhí)行時(shí)間的差別也是很大的,通過以下例題可以對(duì)指令的執(zhí)行時(shí)間有一個(gè)具體的了解。
【例3.11】設(shè)8086的時(shí)鐘頻率為5MHz(即時(shí)鐘周期=0.2μs),試求兩個(gè)字節(jié)相加的ADD指令在各種尋址方式下,指令的執(zhí)行時(shí)間t。
(1)目的操作數(shù)和源操作數(shù)均為寄存器操作數(shù)。需要3個(gè)時(shí)鐘周期,即
t=3×0.2=0.6(μs)
(2)目的操作數(shù)為寄存器操作數(shù),源操作數(shù)為基址變址尋址的存儲(chǔ)器操作數(shù)。需要的時(shí)鐘數(shù)為
t=9+EA=9+12=21(T)
第一項(xiàng)的9為這種尋址方式下指令的基本運(yùn)算和基本操作時(shí)間,第二項(xiàng)為計(jì)算EA的時(shí)間,即
t=21×0.2(μs)=4.2(μs)
(3)目的操作數(shù)為基址變址尋址的存儲(chǔ)器操作數(shù),源操作數(shù)為寄存器操作數(shù)。需要的時(shí)鐘數(shù)為
t=16+EA=16+12=28(T)=5.6(μs)
第一項(xiàng)的16為這種尋址方式下指令的基本運(yùn)算和基本操作時(shí)間,第二項(xiàng)為計(jì)算EA的時(shí)間。
對(duì)于其他的尋址方式下ADD指令的執(zhí)行時(shí)間,請(qǐng)讀者練習(xí)計(jì)算。
從上述的例子可以看出:對(duì)于同一條ADD指令而言,因?qū)ぶ贩绞讲煌瑘?zhí)行指令的時(shí)間也不同,即執(zhí)行的效率有差異,有時(shí)這種差異還很大。從表3.2還可以得知,同一類的指令使用不同的尋址方式時(shí)指令的長(zhǎng)度也不一樣,占用存儲(chǔ)器的字節(jié)數(shù)差異也很大。當(dāng)一個(gè)實(shí)際的應(yīng)用程序要求運(yùn)行效率較高和占用空間較小時(shí),程序的設(shè)計(jì)者不僅要研究算法、數(shù)據(jù)結(jié)構(gòu),還要研究指令與尋址方式的選用,才能編制出高效而簡(jiǎn)潔的程序。
3.4 Intel8086/8088指令系統(tǒng)
8086/8088指令系統(tǒng)包括約百種指令助記符,它們與尋址方式結(jié)合,再加上操作數(shù)字節(jié)數(shù)的不同,可以構(gòu)成上千種指令。這些指令按照功能可分為6類。
(1)數(shù)據(jù)傳送指令;
(2)算術(shù)運(yùn)算指令;
(3)位操作指令;
(4)串操作指令;
(5)轉(zhuǎn)移指令;
(6)處理器控制指令。
本節(jié)將主要介紹前3類指令的格式和功能,后3類指令本節(jié)僅作概要介紹,詳情將在后面的相關(guān)章節(jié)中講解。為便于指令的介紹,現(xiàn)作以下約定。
(1)指令中的IMM表示立即數(shù),IMM8僅表示8位立即數(shù),IMM16僅表示16位立即數(shù)。
(2)指令中的REG表示寄存器操作數(shù)。它可代表8位寄存器AH、AL、BH、BL、CH、CL、DH和DL,以及16位寄存器AX、BX、CX、DX、SP、BP、SI和DI。REG8僅表示8位寄存器,REG16僅表示16位寄存器。指令中的SEGREG表示段寄存器操作數(shù)。它可代表CS、DS、ES及SS。
(3)指令中的MEM表示存儲(chǔ)器操作數(shù),它可以表示任何一種存儲(chǔ)器尋址方式下的操作數(shù)。MEM8、MEM16及MEM32分別表示8位、16位及32位存儲(chǔ)器操作數(shù)。
(4)在對(duì)指令功能作說明時(shí),用圓括號(hào)來表示所括起部分的內(nèi)容。例如用(AX)表示AX的內(nèi)容,用(2040H)表示偏移地址為2040H的存儲(chǔ)單元的內(nèi)容。
(5)在指令的圖示中,對(duì)于存儲(chǔ)器單元一般只標(biāo)出偏移地址。
3.4.1 數(shù)據(jù)傳送指令
數(shù)據(jù)傳送指令用于寄存器、存儲(chǔ)器或輸入/輸出端口之間傳送數(shù)據(jù)或地址,這類指令共14條,按其特點(diǎn)可分為四組,如表3.4所示。
表3.4 數(shù)據(jù)傳送指令表

1.通用數(shù)據(jù)傳送指令
(1)MOV目的操作數(shù),源操作數(shù)把源操作數(shù)傳送到目的操作數(shù)。
【例3.12】MOV AX,BX ;AX←(BX), 即將BX的內(nèi)容傳送到AX中; MOV CL,80H ;CL←80H; MOV AL,[2000H] ;AL←(2000H), 即將EA為2000H(段地址取DS的值) 單元的值傳送到AL中。
說明:
① 源操作數(shù)不變(一般帶有源操作數(shù)的8086/8088指令都不改變?cè)床僮鲾?shù)的內(nèi)容,本書對(duì)于例外指令將予以說明)。
② 立即數(shù)、段寄存器CS不能作為目的操作數(shù)。源操作數(shù)和目的操作數(shù)不能同為存儲(chǔ)器操作數(shù),如圖3.8所示。

圖3.8 數(shù)據(jù)傳送關(guān)系圖
以下指令均是錯(cuò)誤的:
MOV 64H, BL
MOV CS, AX
MOV [2000H], [BX]
③ 源操作數(shù)和目的操作數(shù)類型必須一致,即同為單字節(jié)數(shù),或同為雙字節(jié)數(shù),當(dāng)指令中只有一個(gè)操作數(shù)的類型明確時(shí),另一個(gè)操作數(shù)被視為同一類型。可以用“BYTE PTR”或“WORD PTR”將一個(gè)存儲(chǔ)器操作數(shù)定義為字節(jié)或字類型。當(dāng)存儲(chǔ)器操作數(shù)為字類型時(shí),寄存器或立即數(shù)的高字節(jié)對(duì)應(yīng)其高地址,低字節(jié)對(duì)應(yīng)其低地址(這種對(duì)應(yīng)關(guān)系亦適用于其他指令)。
④ MOV指令的執(zhí)行不影響標(biāo)志寄存器。
【例3.13】MOV [2000H],AX
將AX的內(nèi)容傳送到偏移地址為2000H的存儲(chǔ)單元中。指令執(zhí)行情況如圖3.9所示。

圖3.9 指令執(zhí)行情況
【例3.14】MOV WORD PTR [BX+SI],80H
當(dāng)(BX)=2080H,(SI)=1040H時(shí),表示將0080H傳送到偏移地址為30C0H的存儲(chǔ)單元中。指令執(zhí)行情況如圖3.10所示。

圖3.10 指令執(zhí)行情況
(2)PUSH源操作數(shù)
將源操作數(shù)壓入堆棧。先將SP的內(nèi)容減2,再將雙字節(jié)的源操作數(shù)傳送到SP所指示的堆棧棧頂。
【例3.15】PUSH BX ;指令執(zhí)行情況如圖3.11所示。

圖3.11 指令執(zhí)行情況
(3)POP目的操作數(shù)
將棧頂內(nèi)容彈至目的操作數(shù)。先將SP所指單元也即堆棧棧頂?shù)囊粋€(gè)字傳送到目的操作數(shù),并將SP的內(nèi)容加2。
【例3.16】POP AX
若該指令緊接在上述PUSH BX指令之后,則指令執(zhí)行情況如圖3.12所示。

圖3.12 指令執(zhí)行情況
堆棧是一個(gè)非常有用的存儲(chǔ)結(jié)構(gòu),它遵循先進(jìn)后出的原則,通常用于子程序的調(diào)用和返回,現(xiàn)場(chǎng)的保護(hù)和恢復(fù)等場(chǎng)合。PUSH和POP指令一般應(yīng)配對(duì)使用。使用時(shí)需注意以下4點(diǎn):
① 堆棧操作指令中,有一個(gè)操作數(shù)是隱含的,這個(gè)操作數(shù)就是(SP)指示的棧頂存儲(chǔ)單元。
② 8086/8088堆棧操作都是字操作,不允許對(duì)字節(jié)操作。例如:PUSH AH不是正確指令。
③ 每執(zhí)行一條入棧指令,(SP)自動(dòng)減2,高字節(jié)和低字節(jié)先后入棧;執(zhí)行出棧指令時(shí),則相反,低字節(jié)和高字節(jié)先后出棧,(SP)自動(dòng)加2。
④ CS寄存器可以入棧,但不能隨意彈出一個(gè)數(shù)據(jù)到CS。
【例3.17】設(shè)在一個(gè)被調(diào)用的子程序中,要使用到AX、BX、CX和DX,子程序的運(yùn)行還可能影響狀態(tài)標(biāo)志。為了使這些寄存器中的數(shù)據(jù)不被破壞,進(jìn)入子程序時(shí)先予以入棧保護(hù),子程序結(jié)束前再做出棧恢復(fù)。子程序中保護(hù)和恢復(fù)的程序段為
SUB1 PROC NEAR ; 定義過程 PUSHF PUSH AX PUSH BX PUSH CX PUSH DX ; 保護(hù)現(xiàn)場(chǎng) ┇ POP DX POP CX POP BX POP AX POPF ; 恢復(fù)現(xiàn)場(chǎng) SUB1 ENDP ; 過程結(jié)束
(4)XCHG目的操作數(shù),源操作數(shù)
把源操作數(shù)和目的操作數(shù)互換。說明:該指令與MOV指令功能上的區(qū)別有兩點(diǎn),其一,該指令不允許使用立即數(shù)和段寄存器作為操作數(shù);其二,該指令改變?cè)床僮鲾?shù)的內(nèi)容。
2.累加器專用傳送指令
(1)XLAT,把(BX)與(AL)相加形成有效地址EA,將該單元中的單字節(jié)數(shù)傳送到AL中。
【例3.18】MOV BX,4C02H MOV AL,1DH XLAT
有關(guān)存儲(chǔ)單元情況如圖3.13所示,則執(zhí)行上述指令后,(AL)=55H。
這是一條專門用于AL和字節(jié)表中某一存儲(chǔ)單元之間進(jìn)行數(shù)據(jù)傳送的指令。字節(jié)表的首地址在BX中,根據(jù)AL設(shè)置的偏移地址,就可以將該單元的內(nèi)容傳送到AL中。
(2)IN累加器,端口地址
從指定端口輸入一個(gè)字節(jié)到AL或輸入一個(gè)字到AX。端口地址以數(shù)值形式給出或通過DX間接給出。當(dāng)端口地址大于255時(shí),則只能由DX間接給出。
【例3.19】IN AX,16H ; 從端口16H輸入一個(gè)字到AX中。

圖3.13 執(zhí)行情況
【例3.20】MOV DX,280H IN AL,DX ; 從端口280H輸入一個(gè)字節(jié)到AL。
說明:該指令及后述的OUT指令是專用于累加器和I/O端口之間進(jìn)行數(shù)據(jù)傳送的指令,操作數(shù)的確定方式有別于前述尋址方式。其一,端口地址不加“[ ]”;其二,使用DX作為專用間址寄存器。
(3)OUT端口地址,累加器
實(shí)現(xiàn)輸出,即與IN指令相反方向的數(shù)據(jù)傳送。
3. 地址傳送指令
地址傳送指令實(shí)現(xiàn)操作數(shù)地址的傳送。
(1)LEA目的操作數(shù),源操作數(shù)
將源操作數(shù)的有效地址EA傳送給通用寄存器。
【例3.21】MOV BX,0408H MOV SI,2000H LEA BP,[BX+SI+6] ; 將240EH送BP(而不是將240EH單元的內(nèi)容送BP!)。
(2)LDS目的操作數(shù),源操作數(shù)
將源操作數(shù)指定的存儲(chǔ)單元中的雙字(通常為段地址和有效地址)傳送給DS及目的操作數(shù),高兩字節(jié)送DS,低兩字節(jié)送目的操作數(shù)。
【例3.22】已知(DS)=30C0H,相關(guān)存儲(chǔ)區(qū)情況及執(zhí)行以下指令的功能如圖3.14所示。

圖3.14 指令執(zhí)行情況
LDS SI,[40H]
(3)LES目的操作數(shù),源操作數(shù)
與LDS指令的區(qū)別僅在于,傳送地址時(shí)將高兩字節(jié)送ES,而不是送DS。
說明:
① 地址傳送指令的源操作數(shù)必須是存儲(chǔ)器操作數(shù),目的操作數(shù)必須是16位通用寄存器。
② LEA指令與LDS、LES指令所傳送的有效地址有區(qū)別。LEA指令所傳送的有效地址為源操作數(shù)的有效地址,而LDS及LES指令所傳送的有效地址在源操作數(shù)所指的存儲(chǔ)單元中。
4. 標(biāo)志傳送指令
這組指令專用于對(duì)標(biāo)志寄存器操作。如前所述,8086/8088標(biāo)志寄存器具有16位,LAHF和SAHF僅對(duì)其低8位操作,而PUSHF和POPF對(duì)整個(gè)標(biāo)志寄存器操作。
(1)LAHF,將標(biāo)志寄存器低8位送AH。
(2)SAHF,將(AH)送標(biāo)志寄存器低8位。
(3)PUSHF,與PUSH指令功能相似,該指令的特殊之處僅在于,壓入堆棧的是標(biāo)志寄存器的內(nèi)容。
(4)POPF,與POP指令功能相似,該指令的特殊之處僅在于,彈出的堆棧的內(nèi)容是送標(biāo)志寄存器。
標(biāo)志傳送指令中SAHF和POPF指令將直接影響標(biāo)志寄存器的內(nèi)容。利用這一特性,可以方便地改變標(biāo)志寄存器中指定位的狀態(tài)。
說明:數(shù)據(jù)傳送指令中僅SAHF及POPF影響標(biāo)志寄存器的內(nèi)容。
3.4.2 算術(shù)運(yùn)算指令
算術(shù)運(yùn)算指令分為二進(jìn)制數(shù)算術(shù)運(yùn)算指令和BCD數(shù)算術(shù)運(yùn)算調(diào)整指令。
1. 二進(jìn)制數(shù)算術(shù)運(yùn)算指令
參加算術(shù)運(yùn)算的二進(jìn)制數(shù)可以是單字節(jié)數(shù)或雙字節(jié)數(shù),也可以是無符號(hào)數(shù)或有符號(hào)數(shù)(有符號(hào)數(shù)在機(jī)器內(nèi)部以補(bǔ)碼形式表示)。由于匯編語言源程序中往往需要判斷運(yùn)算結(jié)果是否超出范圍,是否為零,是否為負(fù)數(shù)等,所以二進(jìn)制數(shù)算術(shù)運(yùn)算指令除了產(chǎn)生與操作數(shù)位數(shù)相同的結(jié)果外,還將影響標(biāo)志寄存器中的相應(yīng)標(biāo)志以便在必要時(shí)實(shí)現(xiàn)上述判斷。該類指令共14條,按照四則運(yùn)算分為4組,如表3.5所示。
表3.5 二進(jìn)制算術(shù)運(yùn)算指令表

注:×表示根據(jù)操作結(jié)果設(shè)置標(biāo)志;-表示標(biāo)志不確定;空白表示標(biāo)志不受影響。
(1)加法指令
① ADD 目的操作數(shù),源操作數(shù)
將源操作數(shù)加到目的操作數(shù),同時(shí)影響狀態(tài)標(biāo)志。
ADD 指令執(zhí)行后對(duì)標(biāo)志的影響:
● OF 字節(jié)運(yùn)算結(jié)果超出字節(jié)有符號(hào)數(shù)的范圍(-128~+127)或字運(yùn)算結(jié)果超出字有符號(hào)數(shù)范圍(-32768~+32767)時(shí),OF=1;否則OF=0。在把操作數(shù)視為有符數(shù)時(shí),可通過該標(biāo)志了解結(jié)果是否溢出。
● SF 運(yùn)算結(jié)果的最高位為1時(shí),SF=1;否則SF=0(即SF與結(jié)果的最高位一致)。
● ZF 運(yùn)算結(jié)果為零時(shí),ZF=1;否則ZF=0。
● AF 運(yùn)算時(shí),D3向D4產(chǎn)生進(jìn)位時(shí)AF=1,否則AF=0。
● PF 運(yùn)算結(jié)果的二進(jìn)制位1的個(gè)數(shù)為偶數(shù)時(shí),PF=1;否則PF=0。
● CF 運(yùn)算時(shí)最高位產(chǎn)生進(jìn)位時(shí),即字節(jié)運(yùn)算結(jié)果超出字節(jié)無符號(hào)數(shù)的范圍(0~255),字運(yùn)算結(jié)果超出字無符號(hào)數(shù)的范圍(0~65535)時(shí),CF=1;否則CF=0。在把操作數(shù)視為無符號(hào)數(shù)時(shí),可通過該標(biāo)志了解結(jié)果是否溢出。
【例3.23】ADD AL,BL
設(shè)(AL)=0A4H,(BL)=5CH,則指令執(zhí)行后,(AL)=0,OF=0,SF=0,ZF=1,AF=1,PF=1,CF=1。
編程者往往要根據(jù)不同情況關(guān)心不同的標(biāo)志位。例如:執(zhí)行該指令時(shí),機(jī)器并不能判別所得數(shù)據(jù)是有符號(hào)數(shù)還是無符號(hào)數(shù),而編程者在使用此指令及其他相關(guān)指令時(shí)總是為了解決某一個(gè)具體問題,從而對(duì)這一點(diǎn)是清楚的。因此,在使用此指令后,將會(huì)根據(jù)所得數(shù)據(jù)是有符號(hào)數(shù)還是無符號(hào)數(shù)來關(guān)心不同的標(biāo)志位。
當(dāng)把相關(guān)數(shù)據(jù)視為有符號(hào)數(shù),從OF=0可知相加結(jié)果未溢出,也即AL的內(nèi)容“0”就是兩個(gè)有符號(hào)數(shù)0A4H(-01011100B)和5CH(+01011100B)之和。
當(dāng)把相關(guān)數(shù)據(jù)視為無符號(hào)數(shù),從CF=1可知相加結(jié)果產(chǎn)生進(jìn)位也即“100000000B”就是兩個(gè)無符號(hào)數(shù)0A4H(10100100B)和5CH(01011100B)之和。
說明:源操作數(shù)和目的操作數(shù)類型必須一致,即同為字節(jié)或同為字,且兩者不能同為存儲(chǔ)器操作數(shù)(這一點(diǎn)適用于所有雙操作數(shù)的算術(shù)運(yùn)算指令)。
② ADC目的操作數(shù),源操作數(shù)
功能與ADD指令基本相同,唯一區(qū)別是:將該指令執(zhí)行前的CF值加至目的操作數(shù)中。該指令主要用于多字節(jié)加法運(yùn)算。
【例3.24】MOV DX, 2000H MOV AX, 8A04H ADD AX, 9D00H ADC DX, 45H
此程序段實(shí)現(xiàn)多字節(jié)數(shù)20008A04H與459D00H的相加。DX存放有被加數(shù)的高兩字節(jié),AX存放有被加數(shù)的低兩字節(jié)。ADD指令實(shí)現(xiàn)兩數(shù)低兩字節(jié)的相加,相加后(AX)=2704H,CF=1(相加結(jié)果超過兩個(gè)字節(jié))。ADC指令實(shí)現(xiàn)兩數(shù)高兩字節(jié)的相加,且將CF(即低兩字節(jié)相加產(chǎn)生的進(jìn)位)加至DX,使DX內(nèi)容為2046H。
③ INC目的操作數(shù)
功能與ADD指令基本相同,區(qū)別有兩點(diǎn):其一,隱含的源操作數(shù)為1;其二,不影響CF標(biāo)志。
該指令常用于某些計(jì)數(shù)器的計(jì)數(shù),或用于修改地址。
【例3.25】MOV SI, 2000H MOV AL, [SI] INC SI ADD AL, [SI] ;(AL)為2000H單元和2001H單元內(nèi)容之和
(2)減法指令
① SUB目的操作數(shù),源操作數(shù)
將目的操作數(shù)減去源操作數(shù),同時(shí)產(chǎn)生相應(yīng)標(biāo)志。SUB指令執(zhí)行后對(duì)標(biāo)志的影響與ADD指令基本相同,只不過這里只有“借位”而無“進(jìn)位”。
② SBB目的操作數(shù),源操作數(shù)
功能與SUB指令基本相同,唯一區(qū)別是:目的操作數(shù)除減去源操作數(shù)外,還要減去該指令執(zhí)行前的CF值。
該指令主要用于多字節(jié)減法運(yùn)算。
③ DEC目的操作數(shù)
功能與SUB指令基本相同,區(qū)別有兩點(diǎn):其一,隱含的源操作數(shù)為1;其二,不影響CF標(biāo)志。
④ NEG目的操作數(shù)
對(duì)目的操作數(shù)取補(bǔ)碼,結(jié)果送目的操作數(shù)。因?yàn)閷?duì)一個(gè)數(shù)取補(bǔ)碼相當(dāng)于用0減去此數(shù),所以該指令也屬于減法運(yùn)算指令。
⑤ CMP目的操作數(shù),源操作數(shù)
功能與SUB指令基本相同,唯一區(qū)別是:目的操作數(shù)不被差值取代。該指令的作用在于根據(jù)兩操作數(shù)的大小關(guān)系產(chǎn)生狀態(tài)標(biāo)志值,以便其后指令根據(jù)狀態(tài)標(biāo)志確定程序流程。
(3)乘法指令
① MUL源操作數(shù)
實(shí)現(xiàn)無符號(hào)數(shù)乘法運(yùn)算。將(AL)或(AX)作為被乘數(shù),源操作數(shù)作為乘數(shù),乘積送AX或送DX、AX。當(dāng)源操作數(shù)為字節(jié)操作數(shù)時(shí),默認(rèn)(AL)為被乘數(shù),乘積送AX;當(dāng)源操作數(shù)為字操作數(shù)時(shí),默認(rèn)(AX)為被乘數(shù),乘積高兩字節(jié)送DX,低兩字節(jié)送AX。指令執(zhí)行情況如圖3.15所示。

圖3.15 乘法指令執(zhí)行情況
例如: MUL CL ;AL、CL中的無符號(hào)數(shù)之積送AX; MUL [SI] ; 此為錯(cuò)誤指令。原因在于,計(jì)算機(jī)無法判別源操作數(shù)是字節(jié)操 作數(shù)抑或字操作數(shù); MUL WORD PTR [SI] ;AX中的無符號(hào)數(shù)與SI所指單元的字無符號(hào)數(shù)相乘,乘積送 DX和AX。
MUL指令影響進(jìn)位標(biāo)志CF和溢出標(biāo)志OF(其他標(biāo)志不確定)。若乘積高半部分(字節(jié)相乘時(shí)乘積中的(AH);字相乘時(shí)乘積中的(DX))非0,則CF=OF=1;否則,CF=OF=0。也即,CF=OF=1標(biāo)志著AH或DX中放有乘積的有效位。
② IMUL源操作數(shù)
功能與MUL指令基本相同。區(qū)別僅在于,該指令實(shí)現(xiàn)有符號(hào)數(shù)乘法運(yùn)算。此指令執(zhí)行后,CF=OF=1亦標(biāo)志著AH或DX中放有乘積的有效位。即標(biāo)志著(AH)或(DX)不是對(duì)應(yīng)的低半部分的符號(hào)擴(kuò)展。
【例3.26】MOV AL,0FCH ;-4送AL; MOV CL,1FH ;+31送CL; IMUL CL ;(AL)與(CL)之積-124送AX, 即(AL)=84H,(AH) =FFH。此時(shí)CF=OF=0, 標(biāo)志著(AH)是(AL)的符號(hào)擴(kuò)展。
(4)除法指令
① DIV源操作數(shù)
實(shí)現(xiàn)無符號(hào)數(shù)除法運(yùn)算。以(AX)或(DX)、(AX)中的內(nèi)容為被除數(shù),源操作數(shù)為除數(shù)。商送AL或AX,余數(shù)送AH或DX。當(dāng)源操作數(shù)為字節(jié)操作數(shù)時(shí),默認(rèn)(AX)為被除數(shù),商送AL,余數(shù)送AH;當(dāng)源操作數(shù)為字操作數(shù)時(shí),默認(rèn)(DX)、(AX)內(nèi)容為被除數(shù),商送AX,余數(shù)送DX。指令執(zhí)行情況如圖3.16所示。

圖3.16 除法指令執(zhí)行情況
【例3.27】MOV AX,1001H ;4097送AX; MOV CL,20H ;32送CL; DIV CL ;(AX)與(CL)相除, 商128送AL, 余數(shù)1送AH。即(AL) =80H,(AH)=01H。
DIV指令執(zhí)行后,各狀態(tài)標(biāo)志位不確定。
說明:當(dāng)源操作數(shù)為字節(jié)類型時(shí),商的范圍為0~255(FFH);當(dāng)源操作數(shù)為字類型時(shí),商的范圍為0~65535(FFFFH)。超出范圍則產(chǎn)生0號(hào)中斷。
② IDIV源操作數(shù)
功能與DIV指令基本相同,區(qū)別在于,該指令實(shí)現(xiàn)有符號(hào)數(shù)除法運(yùn)算。另外,8086/8088指令系統(tǒng)中規(guī)定余數(shù)的符號(hào)與被除數(shù)符號(hào)相同。例如:
MOV CX,4 IDIV CX ; 若已知DX、AX中放有4001H, 則該指令執(zhí)行后,(AX)=1000H, (DX)=0001H。若已知DX、AX中放有-4001H, 則該指令執(zhí)行后, (AX)=F000H(即-1000H),(DX)=FFFFH(即-1)。
③ CBW
將(AL)的符號(hào)位擴(kuò)展到AH中(即使得AH各位與AL最高位相同),該指令常用在IDIV指令之前。CBW指令執(zhí)行后,各狀態(tài)標(biāo)志位不確定。例如:
MOV AL, 76H ;+76H送AL; CBW ;0076H送AX, 即+0076H送AX。 又如:MOV AL,98H ;-68H送AL; CBW ;FF98H送AX, 即-0068H送AX。
④ CWD
功能與CBW基本相同,區(qū)別僅在于,該指令是將(AX)的符號(hào)位擴(kuò)展到DX中。
2.十進(jìn)制數(shù)算術(shù)運(yùn)算調(diào)整指令
前面所述的算術(shù)運(yùn)算都是針對(duì)二進(jìn)制數(shù),但人們最為常用的卻是十進(jìn)制數(shù)。在用計(jì)算機(jī)進(jìn)行算術(shù)運(yùn)算時(shí),可以先將操作數(shù)做十→二進(jìn)制轉(zhuǎn)換,然后做二進(jìn)制數(shù)算術(shù)運(yùn)算,再將結(jié)果做二→十進(jìn)制轉(zhuǎn)換。為了便于十進(jìn)制數(shù)的運(yùn)算,8086/8088系統(tǒng)還提供了一組十進(jìn)制數(shù)算術(shù)運(yùn)算調(diào)整指令,該類指令將在5.2.1中詳細(xì)介紹。
3.4.3 位操作指令
8086/8088提供的位操作指令包括邏輯運(yùn)算指令和移位指令,這類指令可直接對(duì)寄存器或存儲(chǔ)器操作數(shù)的位進(jìn)行操作,如表3.6所示。
表3.6 位操作指令表

注:×表示根據(jù)操作結(jié)果設(shè)置標(biāo)志;-表示標(biāo)志不確定;空白表示標(biāo)志不受影響。
1. 邏輯運(yùn)算指令
(1)NOT目的操作數(shù)
將目的操作數(shù)按位取反,結(jié)果送目的操作數(shù)。例如
MOV AX,0 NOT AX ; 使(AX)為FFFFH。
(2)AND目的操作數(shù),源操作數(shù)
將目的操作數(shù)與源操作數(shù)按位相與,結(jié)果送目的操作數(shù)。當(dāng)兩個(gè)操作數(shù)的對(duì)應(yīng)位都為1時(shí),結(jié)果的對(duì)應(yīng)位為1;否則為0。該指令常用于屏蔽目的操作的某些位,即使得目的操作數(shù)的某些位置0,其余保持不變。例如
MOV AL,49H AND AL,0FH ; 使(AL)=09H, 即屏蔽(AL)的高4位, 而低4位不變。
(3)OR目的操作數(shù),源操作數(shù)
將目的操作數(shù)與源操作數(shù)按位相或,結(jié)果送目的操作數(shù)。當(dāng)兩個(gè)操作數(shù)的對(duì)應(yīng)位都為0時(shí),結(jié)果的對(duì)應(yīng)位為0;否則為1。該指令常用于使目的操作數(shù)的某些位置1,其余位保持不變。
例如(4)XOR目的操作數(shù),源操作數(shù)
MOV AL,49H OR AL,3CH ; 使(AL)=7DH, 即使得(AL)中間4位置1, 其余位保持不變。
將目的操作數(shù)與源操作數(shù)按位作異或操作,結(jié)果送目的操作數(shù)。當(dāng)兩個(gè)操作數(shù)的對(duì)應(yīng)位不同時(shí),結(jié)果的對(duì)應(yīng)位為1;否則為0。該指令常用于判斷兩個(gè)數(shù)中哪些位不同,或用于改變指定位的狀態(tài)。例如
MOV DH, 12H XOR DH, 80H ; 使(DH)=92H, 即改變DH最高位狀態(tài)。 又如:XOR AX, AX ; 使(AX)=0。
(5)TEST目的操作數(shù),源操作數(shù)
功能與AND指令基本相同,唯一區(qū)別是:目的操作數(shù)保持不變。該指令常用于檢測(cè)某種條件是否滿足,但又不希望改變目的操作數(shù)的場(chǎng)合。例如
TEST AL,01H ; 可用此指令檢測(cè)AL最低位的狀態(tài)。若AL最低位為0, 則兩操作數(shù)按位相 與的結(jié)果為0, 從而ZF=1; 若AL最低位為1, 則結(jié)果為1, 從而 ZF=0。
說明:邏輯運(yùn)算指令中的兩個(gè)操作數(shù)不能同為存儲(chǔ)器操作數(shù)。
2. 移位指令
移位指令包括算術(shù)移位指令、邏輯移位指令和循環(huán)移位指令。這些指令只有目的操作數(shù)而無源操作數(shù),并在指令中給出移位的位數(shù)。而且此位數(shù)只能用1或CL表示。
(1)算術(shù)、邏輯移位指令
算術(shù)移位指令(SAL、SAR)用于有符號(hào)數(shù),而邏輯移位指令(SHL、SHR)用于無符號(hào)數(shù)。操作數(shù)的左移意味著小數(shù)點(diǎn)相對(duì)右移,而操作數(shù)的右移意味著小數(shù)點(diǎn)相對(duì)左移。算術(shù)、邏輯移位指令的功能如圖3.17所示。

圖3.17
① SHL/SAL 目的操作數(shù),計(jì)數(shù)
SHL指令和SAL指令功能完全相同。將目的操作數(shù)左移若干位,每左移一位,最低位補(bǔ)0,最高位送CF。該指令可以方便地實(shí)現(xiàn)有符號(hào)數(shù)和無符號(hào)數(shù)乘以2n的運(yùn)算(n為移位計(jì)數(shù)值),不過在使用時(shí)要注意是否發(fā)生溢出。例如
MOV AL,16H SHL AL, 1 ; 使(AL)即00010110B左移1位。移位后,(AL)=00101100B, 是原值的2 倍。CF 值為0。 又如:MOV BH,0EEH MOV CL, 2 SAL BH,CL ; 使BH中的有符號(hào)數(shù)11101110B左移2 位。移位后(BH)=10111000B, 是 原值的4倍(原值為-00010010B, 即-18; 移位后的值為-01001000, 即 -72)。
② SHR 目的操作數(shù),計(jì)數(shù)
將目的操作數(shù)右移若干位。每右移一位,高位均補(bǔ)0,最低位送CF。該指令可以方便地實(shí)現(xiàn)無符號(hào)數(shù)除以2n的運(yùn)算。
③ SAR 目的操作數(shù),計(jì)數(shù)
將目的操作數(shù)右移若干位。每右移一位,高位均保持不變,最低位送CF。該指令可以方便地實(shí)現(xiàn)有符號(hào)數(shù)除以2n的運(yùn)算。例如
MOV AL, 0F8H SAR AL, 1 ; 使AL中的有符號(hào)數(shù)11111000B右移1位。移位后(AL)=11111100B, 是 原值的1/2(原值為-00001000B, 即-8; 移位后的值為-00000100B, 即-4)。
(2)循環(huán)移位指令
循環(huán)移位指令的功能如圖3.18所示。

圖3.18
① ROL 目的操作數(shù),計(jì)數(shù)
將目的操作數(shù)循環(huán)左移若干位。每左移一位,左移前的最高位送最低位以及CF。
② ROR 目的操作數(shù),計(jì)數(shù)
將目的操作數(shù)循環(huán)右移若干位。每右移一位,右移前的最低位送最高位以及CF。
③ RCL 目的操作數(shù),計(jì)數(shù)
將目的操作數(shù)連同CF循環(huán)左移若干位。每左移一位,左移前的最高位送CF,左移前的CF送最低位。
④ RCR 目的操作數(shù),計(jì)數(shù)
將目的操作數(shù)連同CF循環(huán)右移若干位。每右移一位,右移前的CF送最高位,右移前的最低位送CF。
【例3.28】 MOV DX, 0FFF9H XOR AX, AX ; 使AX,CF清0。 SAR DX, 1 RCR AX, 1 SAR DX, 1 RCR AX, 1
該程序段實(shí)現(xiàn)DX、AX中的有符號(hào)數(shù)FFF90000H右移兩位。移位后DX、AX內(nèi)容為FFFE 4000H,是原值的1/4(原值為-00000000000001110000000000000000B,移位后的值為-00000000000000011100000000000000B)。
3.4.4 串操作指令
串是指存儲(chǔ)器中的字節(jié)串(字節(jié)序列)或字串(字序列)。8086/8088系統(tǒng)對(duì)串的操作提供了5種基本的指令以及與之配合使用的重復(fù)前綴。它們常用于循環(huán)結(jié)構(gòu),本書將在7.2中對(duì)此做介紹。
3.4.5 轉(zhuǎn)移指令
一般情況下指令是順序地逐條執(zhí)行的。但有時(shí)需要改變這種執(zhí)行流程,8086/8088系統(tǒng)為此提供了轉(zhuǎn)移指令。轉(zhuǎn)移指令用于分支結(jié)構(gòu),本書將在6.2中對(duì)此做介紹。
3.4.6 處理器控制指令
處理器控制指令用于控制CPU的某些功能,如表3.7所示。
表3.7 處理器控制指令表

3.5 Intel80x86及Pentium指令系統(tǒng)
3.5.1 Intel80386新增和擴(kuò)充指令
80386是80X86微處理器系列發(fā)展中的里程碑。80386指令系統(tǒng)包括了所有80286指令,并對(duì)80286的部分指令進(jìn)行了功能擴(kuò)充,還新增了一些指令,特別指出的是,80386提供了32位尋址方式可對(duì)32位數(shù)據(jù)直接操作。所有16位指令均可擴(kuò)充為32位指令。80386有8個(gè)32位通用寄存器:EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI。它們分別是原來的16位通用寄存器AX,CX,DX,BX,SP,BP,SI,DI的擴(kuò)展(詳細(xì)的寄存器結(jié)構(gòu)在第2.3節(jié)已介紹),這些32位通用寄存器的低16位也可以作為16位通用寄存器獨(dú)立存取數(shù)據(jù),也就是說80386對(duì)8086,80286是向上兼容的。對(duì)于數(shù)據(jù)段寄存器,80386在原有基礎(chǔ)上增加了兩個(gè):FS和GS。80386的標(biāo)志寄存器擴(kuò)展到了32位,其中某些位沒有定義。80386在實(shí)地址模式下有9個(gè)標(biāo)志位可用,在保護(hù)虛地址模式下有13個(gè)標(biāo)志位可用,擴(kuò)展后的標(biāo)志寄存器也可稱為E標(biāo)志寄存器(EFR)EFLAGS。
80386有實(shí)地址模式、保護(hù)虛地址模式和虛擬8086模式3種工作方式,在DOS環(huán)境中只能運(yùn)行于實(shí)地址模式,可做為超高速8086芯片使用。
1. 數(shù)據(jù)傳送與擴(kuò)展指令
(1)MOVSX寄存器,寄存器/存儲(chǔ)器
將源操作數(shù)傳送到目的操作數(shù)中。目的操作可以是16位或32位寄存器;源操作數(shù)可以是寄存器或存儲(chǔ)器操作數(shù),其位數(shù)應(yīng)小于或等于目的操作數(shù)的位數(shù)。當(dāng)源操作數(shù)的位數(shù)少于目的操作數(shù)時(shí),目的操作數(shù)的高位用源操作數(shù)的符號(hào)位填補(bǔ)。此指令適用于有符號(hào)數(shù)的傳送與擴(kuò)展。該指令不影響狀態(tài)標(biāo)志位。
(2)MOVZX寄存器,寄存器/存儲(chǔ)器
與MOVSX功能基本相同,唯一區(qū)別在于,當(dāng)源操作數(shù)的位數(shù)少于目的操作數(shù)位數(shù)時(shí),目的操作數(shù)的高位用“0”填補(bǔ)。該指令適用于無符號(hào)數(shù)的傳送與擴(kuò)展。例如
MOV DL,86H MOVSX AX,DL ;86H擴(kuò)展成FF86H送AX; MOVSX ECX,DL ;86H擴(kuò)展成FFFF FF86H送ECX; MOVZX BX,DL ;86H擴(kuò)展成0086H送BX; 又如: MOV WORD PTR[BX],68H ;0068H送BX所指定的內(nèi)存單元; MOV AX,[BX] ;0068H送AX; MOVSX ESI,WORD PTR[BX] ; 將 0068H擴(kuò)展成00000068H送ESI; MOVZX EDI,WORD PTR[BX] ; 將0068H擴(kuò)展成00000068H送EDI。
2. 堆棧操作指令
(1)PUSH 8/16 /32位立即數(shù)
將8/16/32位立即數(shù)壓入堆棧。當(dāng)然該指令執(zhí)行后SP的值將減2或者4。通常使用以下方法來區(qū)別操作數(shù)是8位,16位還是32位立即數(shù)。
【例3.29】PUSH 'A' ; 將0041H壓入堆棧(8位立即數(shù)) PUSHW 15H ; 將0015H壓入堆棧(16位立即數(shù)) PUSHD 20H ; 將00000020H壓入堆棧(32位立即數(shù))
在8086/8088指令系統(tǒng)中,PUSH指令允許的操作數(shù)只能是兩字節(jié)的寄存器操作數(shù)或兩字節(jié)的存儲(chǔ)器操作數(shù)。該指令中如果給出的數(shù)不夠16或32位,則自動(dòng)擴(kuò)展為16或32位后壓入堆棧。
(2)PUSHA
將所有通用寄存器AX,CX,DX,BX,SP,BP,SI,DI的內(nèi)容按順序壓入堆棧,入棧的SP值是執(zhí)行該指令之前SP的值。在執(zhí)行完本指令后,SP值減16,如圖3.19所示。
(3)PUSHAD
將所有通用寄存器EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI的內(nèi)容順序壓入堆棧,其中壓入堆棧的ESP是該指令執(zhí)行前ESP的值。執(zhí)行該指令后,ESP值減32。

圖3.19 執(zhí)行PUSHA指令的堆棧情況
(4)POPA
將棧頂?shù)膬?nèi)容順序彈至DI,SI,BP,SP,BX,DX,CX,AX(次序與PUSHA指令相反)。SP中的值是堆棧中所有通用寄存器彈出后,堆棧指針實(shí)際指向的值(不是棧中保存的SP值),也即該指令執(zhí)行后SP的值,可以通過加16來恢復(fù),如圖3.20所示。PUSHA及POPA均不影響狀態(tài)標(biāo)志位。

圖3.20 執(zhí)行POPA指令的堆棧情況
【例3.30】一個(gè)子程序被調(diào)用時(shí),保存所有通用寄存器,可用下述指令實(shí)現(xiàn): PUSHA CALL SUB1 POPA
顯然使用上述指令比使用PUSH指令和POP指令更方便。
(5)POPAD
將當(dāng)前棧頂內(nèi)容順序彈至EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX(次序與PUSHAD指令相反),但是最終ESP的值為彈出操作對(duì)堆棧指針調(diào)整后的值(而不是堆棧中保存的ESP的值)。也即執(zhí)行該指令后ESP的值,可以通過增加32來恢復(fù)。
(6)PUSHFD
將32位標(biāo)志寄存器EFLAGS的內(nèi)容壓入堆棧。
(7)POPFD
將當(dāng)前棧頂?shù)?字節(jié)內(nèi)容彈至EFLAGS寄存器。
上述堆棧操作指令中,除POPFD以外,其余均不影響狀態(tài)標(biāo)志位。
(8)設(shè)置堆棧空間指令
格式:ENTER 16位立即數(shù),8位立即數(shù)。
ENTER指令使用兩個(gè)操作數(shù),16位立即數(shù)表示堆棧空間的大小,也即表示給當(dāng)前過程分配多少字節(jié)的堆棧空間,8位立即數(shù)指出在高級(jí)語言內(nèi)(如Pascal語言)調(diào)用自身的次數(shù),也即嵌套層數(shù)。
說明:該指令使用BP寄存器而非SP作為棧基值。
【例3.31】ENTER 6,0
該指令為過程分配了6個(gè)字節(jié)的堆棧空間,其嵌套層數(shù)為0。指令執(zhí)行情況如圖3.21所示。

圖3.21 ENTER指令執(zhí)行情況
(9)撤銷堆棧空間指令
格式:LEAVE
該指令無操作數(shù),撤銷由ENTER指令建立的堆棧空間。
【例3.32】有一個(gè)16位參數(shù),在主程序中需交給一個(gè)子程序處理,結(jié)果再傳回主程序,可使用堆棧空間指令完成上述工作。
調(diào)用子程序的過程,參數(shù)存入到堆棧中 ENTER 4,0 ; 建立4字節(jié)堆棧空間 MOV AX,Number1 ; 保存參數(shù)1 MOV [BP-4],AX MOV AX,Number2 ; 保存參數(shù)2 MOV [BP-2],AX CALL COURSE ; 調(diào)用子程序 MOV AX,[BP-4] ; 取結(jié)果1 MOV Number1,AX MOV AX,[BP-2] ; 取結(jié)果2 MOV Number2,AX LEAVE ; 撤銷堆棧空間 ┇ ; 使用堆棧處理數(shù)據(jù)的子程序 COURSE PROC NEAR PUSHA MOV AX,[BP-4] ; 取參數(shù)1 MOV DX,[BP-2] ; 取參數(shù)2 ┇ ; 參數(shù)處理 ┇ MOV [BP-4],AX ; 保存結(jié)果1 MOV [BP-2],DX ; 保存結(jié)果2 POPA RET COURSE END
3. 地址傳送指令
(1)LFS寄存器,存儲(chǔ)器
將源操作數(shù)所指存儲(chǔ)單元的4字節(jié)或6字節(jié)內(nèi)容送指定的寄存器及段寄存器FS(FS及GS為80386新增的段寄存器)。
當(dāng)目的操作數(shù)為16位寄存器時(shí),將4字節(jié)的存儲(chǔ)器操作數(shù)中的低兩字節(jié)送指定寄存器,高兩字節(jié)送段寄存器FS;當(dāng)目的操作數(shù)為32位寄存器時(shí),將6字節(jié)的存儲(chǔ)器操作數(shù)中的低4字節(jié)送指定寄存器,高兩字節(jié)送段寄存器FS。該指令不影響狀態(tài)標(biāo)志位。
【例3.33】LFS BX, ARRAY
指令執(zhí)行情況如圖3.22所示。

圖3.22 指令執(zhí)行情況
(2)LGS寄存器,存儲(chǔ)器
該指令與LFS指令功能基本相同,唯一區(qū)別在于,該指令所涉及的段寄存器為GS。
(3)LSS寄存器,存儲(chǔ)器
該指令與LFS指令功能基本相同,唯一區(qū)別在于,該指令所涉及的段寄存器為SS。
4. 運(yùn)算指令
在8086/8088指令系統(tǒng)中,乘法指令只給出一個(gè)操作數(shù),另一個(gè)操作數(shù)隱含在AL或AX中,80386將其擴(kuò)充為可以有兩個(gè)或3個(gè)操作數(shù)。
(1)IMUL寄存器,寄存器/存儲(chǔ)器/立即數(shù)
將通用寄存器中的有符號(hào)數(shù)作為被乘數(shù),相同位數(shù)通用寄存器、存儲(chǔ)單元中的有符號(hào)數(shù)或立即數(shù)(如立即數(shù)與目的操作數(shù)不等長(zhǎng),運(yùn)算時(shí)機(jī)器會(huì)自動(dòng)將其符號(hào)擴(kuò)展成與目的操作數(shù)等長(zhǎng))作為乘數(shù),乘積送目的操作數(shù)。若乘積溢出,溢出位部分將丟失,且將OF及CF置1;否則將OF及CF置0。
說明:目的操作數(shù)的位數(shù)必須與源操作數(shù)位數(shù)相同。
例如: IMUL DX, 9
(2)IMUL寄存器,寄存器/存儲(chǔ)器,立即數(shù)
與前一指令功能基本相同,唯一區(qū)別在于,寄存器/存儲(chǔ)器為被乘數(shù),立即數(shù)為乘數(shù),乘積存放在第一個(gè)操作數(shù)中。例如:
IMUL EAX,DWORD DTR[BX],9 ; 將BX所指定的4字節(jié)存儲(chǔ)器操作數(shù)乘以9, 乘積送32位 通用寄存器EAX。
(3)CWDE
將AX中16位有符號(hào)數(shù)的符號(hào)位擴(kuò)展到EAX的高16位中,即把AX的16位有符號(hào)數(shù)擴(kuò)展為32位后,送EAX。
(4)CDQ
將EAX中32位有符號(hào)數(shù)擴(kuò)展到EDX:EAX寄存器對(duì)中,使之成為64位有符號(hào)數(shù),即將EAX中的符號(hào)位擴(kuò)展到EDX中。
【例3.34】若DATA1中為16位有符號(hào)數(shù),值為-5,DATA2中為32位有符號(hào)數(shù),值為-7。將DATA1擴(kuò)展成32位有符號(hào)數(shù),將DATA2擴(kuò)展成64位有符號(hào)數(shù)。
MOV AX,DATA1 ;AX中為-5(FFFBH) CWDE ; 擴(kuò)展后EAX中為32位的-5(FFFF FFFBH) MOV EAX,DATA2 ;EAX中為-7(FFFF FFF9H) CDQ ; 擴(kuò)展后EDX:EAX中為64位的-7(FFFF FFFF FFFF FFF9H)
5. 移位指令
(1)移位指令助記符 寄存器/存儲(chǔ)器 立即數(shù)(≤31)
8086中有8條移位指令,移位計(jì)數(shù)使用CL或1表示,且規(guī)定當(dāng)移位次數(shù)大于1時(shí),必須使用CL。從80286開始,則修改了上述的限制,當(dāng)移位次數(shù)為1~31時(shí),允許使用立即數(shù)。例如:
ROL AX,5 SHL WORD PTR[BX],18
(2)SHLD寄存器/存儲(chǔ)器,寄存器,CL/立即數(shù)
將第一操作數(shù)(16位或32位通用寄存器或存儲(chǔ)單元)左移若干位(左移位數(shù)由8位立即數(shù)或CL指定),空出位用第二操作數(shù)(與第一操作數(shù)長(zhǎng)度相同的通用寄存器)高位部分填補(bǔ),但第二操作數(shù)的內(nèi)容不變,CF標(biāo)志位中保留第一操作數(shù)最后的移出位。若僅移一位,當(dāng)CF值與移位后的第一操作數(shù)的符號(hào)位不一致時(shí),OF置1;否則OF置0。移位過程如圖3.23所示。

圖3.23 SHLD指令功能
【例3.35】MOV AX,8321H MOV DX,5678H SHLD AX,DX,1 ;(AX)=0642H,DX=5678H,CF=1,OF=1; SHLD AX,DX,2 ;(AX)=1909H,DX=5678H,CF=0,OF=0。
(3)SHRD寄存器/存儲(chǔ)器,寄存器,CL/立即數(shù)
將第一操作數(shù)(16位或32位通用寄存器或存儲(chǔ)器單元)右移若干位(右移位數(shù)由CL或8位立即數(shù)指定),空出位用第二操作數(shù)(與第一操作數(shù)長(zhǎng)度相同的通用寄存器)低位部分填補(bǔ),指令執(zhí)行后,第二操作數(shù)內(nèi)容不變,CF標(biāo)志位中保留第一操作數(shù)最后的移出位。移位過程如圖3.24所示。

圖3.24 SHRD指令功能
【例3.36】MOV AX,4B02H ;AX=0100101100000010 MOV BX,6040H ;BX=0110000001000000 SHRD AX,BX,7 ;AX右移7位,BX的低7位移入AX中, 結(jié)果為AX=10000000 10010110(8096H), BX=6040H(保持不變), CF=0。
指令執(zhí)行情況如圖3.25所示。

圖3.25 指令執(zhí)行情況
6. 位操作指令
(1)位測(cè)試及設(shè)置指令
測(cè)試指令可用來對(duì)指定位進(jìn)行測(cè)試,因而可根據(jù)該位的值來控制程序流的執(zhí)行方向,而置位指令可對(duì)指定的位進(jìn)行設(shè)置。
① BT 存器/存儲(chǔ)器地址,寄存器/立即數(shù)
第一操作數(shù)(16位或32位通用寄存器或存儲(chǔ)單元)指定要測(cè)試的內(nèi)容,第二操作數(shù)(與第一操作數(shù)同長(zhǎng)度的通用寄存器或8位立即數(shù))指定要測(cè)試的位,將被測(cè)內(nèi)容的指定測(cè)試位的值送CF,其他狀態(tài)標(biāo)志不確定。
【例3.37】設(shè)BX指向一個(gè)存儲(chǔ)單元數(shù),CX值為4。
BT [BX],CX ; 檢查由BX指向數(shù)據(jù)的第4位, 并將該位值送入CF; JC Swhere ; 若CF=1, 則轉(zhuǎn)移。
若用8086指令完成,可寫成:
MOV AX,[BX] ; 將BX指向的數(shù)裝入AX中; TEST AX,10H ; 檢查第4位是否為1; JNZ Swhere ; 若CF=1, 則轉(zhuǎn)移。
② BTC 存器/存儲(chǔ)器地址,寄存器/立即數(shù)
該指令在BT指令功能的基礎(chǔ)上,將被測(cè)位取反。
③ BTR 存器/存儲(chǔ)器,寄存器/立即數(shù)
該指令在BT指令功能的基礎(chǔ)上,將被測(cè)位清0。
④ BTS 存器/存儲(chǔ)器,寄存器/立即數(shù)
該指令在BT指令功能基礎(chǔ)上,將被測(cè)位置1。
【例3.38】MOV AX, 1234H
(2)位掃描指令
BT AX,2 ;(AX)=1234H,CF=1 BTC AX,2 ;(AX)=1230H,CF=1 BTR AX,2 ;(AX)=1230H,CF=0 BTS AX,2 ;(AX)=1234H,CF=0
位掃描指令用于找出寄存器或存儲(chǔ)器地址中所存數(shù)據(jù)的第一個(gè)或最后一個(gè)是1的位。該指令可用于檢查寄存器或存儲(chǔ)器或存儲(chǔ)單元是否為0。
① BSF 寄存器,寄存器/存儲(chǔ)器
對(duì)第二操作數(shù)(16位或32位通用寄存器或存儲(chǔ)器)從最低位到最高位進(jìn)行掃描,將首先掃描到的“1”的位號(hào)送第一操作數(shù)(與第二操作數(shù)位數(shù)相同的通用寄存器),且使ZF置0。若第二操作數(shù)的各位均為0,則第一操作數(shù)的值不確定,且使ZF置1。其他狀態(tài)標(biāo)志位不確定。
② BSR 寄存器,寄存器/存儲(chǔ)器
與BSF指令功能基本相同,唯一區(qū)別在于,該指令是從最高位到最低位進(jìn)行掃描。
例如: MOV EAX,01234567H BSR ECX,EAX ;(ECX)=18H,ZF=0 BSF AX,CX ;(AX)=03H,ZF=0
7. 條件設(shè)置指令
這組80386特有的指令用于測(cè)試指定的標(biāo)志位所處的狀態(tài),并根據(jù)測(cè)試結(jié)果,將指定的一個(gè)8位寄存器或內(nèi)存單元置1或置0。它們類似于條件轉(zhuǎn)移指令中的標(biāo)志位測(cè)試,但前者根據(jù)測(cè)試結(jié)果將操作數(shù)置1或置0,而后者根據(jù)測(cè)試結(jié)果決定轉(zhuǎn)移還是不轉(zhuǎn)移。
指令格式為
SET條件 寄存器/存儲(chǔ)器
說明:條件是指令助記符的一部分,用于指定要測(cè)試的標(biāo)志位。例如
SETZ AL ; 當(dāng)ZF=1, 則(AL)=1, 否則(AL)=0 SETNC BYTE PTR[BX] ; 當(dāng)CF=0, 則BX所指字節(jié)單元內(nèi)容為1
8. 內(nèi)存范圍檢查指令
格式:BOUND 16位寄存器,32位存儲(chǔ)器
以32位存儲(chǔ)器低兩字節(jié)的內(nèi)容為下界,高兩字節(jié)的內(nèi)容為上界。若16位寄存器的內(nèi)容在此上、下界表示的地址范圍內(nèi),程序正常執(zhí)行;否則產(chǎn)生INT 5中斷(DOS并未提供該類型中斷處理程序,使用時(shí)用戶需自行編寫)。當(dāng)出現(xiàn)這種中斷時(shí),返回地址指向BOUND指令,而不是BOUND后面的指令,這與返回地址指向程序中下一條指令的正常中斷是有區(qū)別的。
【例3.39】BOUND指令的應(yīng)用。
DATA SEGMENT BOTTOM EQU 0 TOP EQU 19 ANS LABEL DWORD ; 給ANS分配32位地址; WANS DW BOTTOM,TOP ; 對(duì)邊界初始化; BOFF DB TOP+1 DUP(?) ; 分配數(shù)組; DATA ENDS CODE SEGMENT ┇ ; 假設(shè)SI為數(shù)組的地址指針; BOUND SI,ANS ; 檢查SI是否在數(shù)據(jù)地址范圍內(nèi), 否則進(jìn)入類型5中斷; MOV DX,BOFF[SI] ; 若在范圍內(nèi), 繼續(xù)使用。 ┇ CODE ENDS
3.5.2 Pentium新增指令
1. 字節(jié)交換指令
格式:BSWAP寄存器
將32位通用寄存器以字節(jié)為單位進(jìn)行高低字節(jié)的交換,即對(duì)指定寄存器的32位操作數(shù)的位31~24與位7~0,位23~16與位15~8交換。該指令不影響狀態(tài)標(biāo)志位。
【例3.40】寄存器(EDX)=12345678H BSWAP EDX 則指令執(zhí)行后,(EDX)=78563412H。
80X86系列處理器按“高高低低”的原則存儲(chǔ)多字節(jié)數(shù)據(jù),但某些處理器按“低低高高”的原則存儲(chǔ)數(shù)據(jù),BSWAP指令特別適宜于這兩種數(shù)據(jù)格式之間的轉(zhuǎn)換。
2. 互換并相加指令
格式:XADD寄存器/存儲(chǔ)器,寄存器
該指令將第一操作數(shù)(8位,16位或32位通用寄存器或存儲(chǔ)單元)與第二操作數(shù)(與第一操作數(shù)位數(shù)相同的通用寄存器)內(nèi)容互換,并將兩者之和送第一操作數(shù)。該指令對(duì)狀態(tài)標(biāo)志位的影響與ADD指令相同。
【例3.41】若BX所指單元內(nèi)容為11223344H,(EAX)=00224466H, XADD [BX],EAX
指令執(zhí)行后,(EAX)=11223344H,而BX所指單元內(nèi)容為1144 77AAH。XADD指令功能相當(dāng)于XCHG和ADD這兩條指令的功能。該指令允許使用LOCK前綴。
3.比較并交換指令
(1)格式:CMPXCHG寄存器/存儲(chǔ)器,寄存器
該指令將第一操作數(shù)(8位,16位或32位通用寄存器或存儲(chǔ)單元)內(nèi)容與對(duì)應(yīng)長(zhǎng)度的累加器(AL,AX或EAX)內(nèi)容作比較,若相等,則使ZF置1,且將第二操作數(shù)(與第一操作數(shù)位數(shù)相同的通用寄存器)內(nèi)容送第一操作數(shù);否則使ZF清0,且第一操作數(shù)送對(duì)應(yīng)累加器。
【例3.42】CMPXCHG ESI,EBX
若(ESI)=(EAX),則ZF=1,且將(EBX)送ESI;否則ZF=0,且將(ESI)送EAX。
(2)8字節(jié)比較交換指令
格式:CMPXCHG8B存儲(chǔ)器
將EDX:EAX中的8字節(jié)值與指定的8字節(jié)存儲(chǔ)器操作數(shù)相比較,若相等,則使ZF置1,且將ECX:EBX中的值送指定的8字節(jié)存儲(chǔ)單元替換原有存儲(chǔ)器操作數(shù);否則使ZF=0,且將指定的8字節(jié)存儲(chǔ)操作數(shù)器送EDX:EAX。
【例3.43】設(shè)BX所指8字節(jié)存儲(chǔ)單元內(nèi)容為0011223344556677H,(EDX)=0,(EAX)=FFFF FFFFH。
CMPXCHG8B [BX]
則該指令執(zhí)行后,(EDX)=00112233H,(EAX)=44556677H,ZF=0。
4.Cache管理指令
(1)使整個(gè)片內(nèi)Cache無效指令
格式:INVD
該指令用于將CPU內(nèi)部Cache的內(nèi)容無效。其具體的操作是刷新內(nèi)部Cache,并分配一個(gè)專用總線周期刷新外部Cache,執(zhí)行該指令不會(huì)將外部Cache中的數(shù)據(jù)寫回主存,即Cache中數(shù)據(jù)自然丟失。
(2)寫回并使Cache無效指令
格式:WBINVD
該指令功能與INVD相似,具體操作是刷新內(nèi)部Cache。并分配一個(gè)專用總線周期將外部Cache的數(shù)據(jù)寫回主存,并在此后的一個(gè)專用總線周期將外部Cache刷新。
(3)使TLB無效指令
格式:INVLPG
該指令使頁(yè)式管理機(jī)構(gòu)內(nèi)的高速緩沖器TLB中的某一項(xiàng)作廢。若TBL中含有一個(gè)存儲(chǔ)器操作數(shù)映象的有效項(xiàng),則該TBL項(xiàng)被標(biāo)記為無效。
5.處理器特征識(shí)別指令
格式: CPUID
根據(jù)EAX中的參數(shù),將處理器的說明信息送EAX,特征標(biāo)志字送EDX。
6.讀時(shí)間標(biāo)記計(jì)數(shù)器指令
格式: RDTSC
將Pentium中的64位時(shí)間標(biāo)記計(jì)數(shù)器的高32位送EDX,低32位送EAX。該計(jì)數(shù)器隨每一個(gè)時(shí)鐘遞增,在Reset后該計(jì)數(shù)器被置0。利用該計(jì)數(shù)器可檢測(cè)程序運(yùn)行性能。
7.讀模型專用寄存器指令
格式: RDMSR
將ECX所指定的模型專用寄存器的內(nèi)容送EDX、EAX,具體來說,高32位送EDX,低32位送EAX。若所指定的模型寄存器不是64位,則EDX、EAX中的對(duì)應(yīng)位無定義。
8.寫模型專用寄存器指令
格式: WRMSP
將EDX、EAX的內(nèi)容送到由ECX指定的模型專用寄存器。具體來說,EDX和EAX的內(nèi)容分別作為高32位和低32位。若指定的模型寄存器有未定義或保留的位,則這些位的內(nèi)容不變。
本小節(jié)只是簡(jiǎn)單介紹了Pentium新增指令,對(duì)這幾條指令的理解和應(yīng)用要求具備Pentium體系結(jié)構(gòu)方面的知識(shí),請(qǐng)參閱有關(guān)文獻(xiàn)資料。
習(xí)題
3.1 分別指出下列指令中源操作數(shù)和目的操作數(shù)的尋址方式。
1)MOV AX,0100H 2)MOV [SI],AL 3)ADC BL,[2000H] 4)AND BYTE PTR[2000H],1 5)MOV 2[BX][DI],DX 6)OR AX,80H[SI]
3.2 指出以下指令是否合法。
1)MOV CS,AX 2)MOV [2000H],AL 3)ADD [2000H],40H 4)MUL AX,BX 5)AND 184CH,AX 6)MOV DS,0 7)INC [BX] 8)SBB AX,[DX] 9)RCL BX,2 10)POP AL 11)XCHG BX,4050H 12)CWB
3.3 試根據(jù)以下要求寫出相應(yīng)的匯編語言指令。
1)將CX寄存器的內(nèi)容與DX寄存器的內(nèi)容相加,結(jié)果存入DX寄存器中。
2)用寄存器BX和DI的基址變址尋址方式把存儲(chǔ)器中的一個(gè)字節(jié)數(shù)據(jù)與AH寄存器的內(nèi)容相加,并把結(jié)果存入AH寄存器中。
3)用寄存器BX和位移量2000H的寄存器相對(duì)尋址方式把存儲(chǔ)器的一個(gè)字?jǐn)?shù)據(jù)和(DX)相加,并把結(jié)果送回存儲(chǔ)器中。
4)將數(shù)0C3H與(BL)寄存器相加,結(jié)果送回BL寄存器中。
5)將存儲(chǔ)器數(shù)據(jù)段中1300H單元(采用直接尋址方式)中的一個(gè)字?jǐn)?shù)據(jù)與立即數(shù)3456H相減,結(jié)果送回存儲(chǔ)器1300H單元。
3.4 假設(shè)AX中的數(shù)據(jù)為6987H,DATE1分別為下列數(shù)值時(shí),執(zhí)行ADD AX,DATE1指令后,標(biāo)志位SF、ZF、CF和OF的狀態(tài)是什么?
1)1234H 2)4801H 3)EB30H 4)902AH
3.5 假設(shè)AX中的數(shù)據(jù)為3760H,DATE1分別為下列數(shù)值時(shí),執(zhí)行CMP AX,DATE1指令后,標(biāo)志位SF、ZF、CF和OF的狀態(tài)是什么?
1)1234H 2)4801H 3)EB30H 4)902AH
3.6 設(shè)(SP)=2040H,(AX)=12D4H,(BX)=36F4H。試回答:
1)執(zhí)行PUSH AX指令后,(SP)=?
2)再執(zhí)行PUSH BX及POP AX指令后,(SP)=?,(AX)=?
3.7 寫出執(zhí)行以下計(jì)算的指令序列,其中X,Y,Z,R和Q均為存放16位帶符號(hào)數(shù)單元的地址。
1)Q←X+(Z-Y) 2)Q←X+(Y+9)-(Z+3) 3)Q←(X*Y)+(Z/R) 4)Q←5*(X-Y)+R/(Z+8)
3.8 現(xiàn)有(DS)=4000H,(BX)=0100H,(SI)=0002H,(40100H)=11H,(40101H)=22H,(40102H)=33H,(40103H)=44H,(41200H)=55H,(41201H)=66H,(41202H)=77H,(41203H)=88H,試說明下列各條指令執(zhí)行完成后AX的內(nèi)容。
1)MOV AX,0100H 2)MOV AX,[BX] 3)MOV AX,1200H 4)MOV AX,BX 5)MOV AX,[BX][SI] 6)MOV AX,1100H[BX] 7)MOV AX,1100H[BX][SI] 8)MOV AX,2[BX]
3.9 已知:(DS)=2000H,(ES) =3000H,(CS)=5000H,(SS)=4000H (AX)=5566H,(BX)=1000H,(BP)=0010H,(21000H)=1122H,(31000H)=7766H,(40010H)= 0FFFFH。
請(qǐng)寫出下列各條指令獨(dú)立執(zhí)行完后,有關(guān)寄存器及存儲(chǔ)單元的內(nèi)容。
1)ADD AL,[BX] 2)AND AX,BX 3)SUB ES:[BX],AX 4)XOR [BP],AX
3.10 在數(shù)據(jù)段DATA中已為0120H單元定義的符號(hào)名為MESS,其中存放的數(shù)據(jù)為1122H。
1)試問以下兩條指令有什么區(qū)別,指令執(zhí)行結(jié)束后AX寄存器的內(nèi)容是什么。
MOV AX,MESS LEA AX,MESS
2)試問以下兩條指令有什么區(qū)別,指令執(zhí)行結(jié)束后AX寄存器的內(nèi)容是什么。
MOV AX,MESS MOV AX,OFFSET MESS
3.11 寫出各種使AL置0的指令。
3.12 用兩種方法實(shí)現(xiàn)將(AL)乘以10值送AX的功能。
3.13 寫一程序段,將附加段2000H~2003H四個(gè)字節(jié)之和送AX。
3.14 假設(shè)(DX)=0F7H,變量DATA1中內(nèi)容為9EH,確定下列每條指令執(zhí)行后的結(jié)果。
1)AND DX,DATA1 2)XOR DX,DATA1 3)OR DX,DATA1 4)SHL DX,1 5)XOR DX,0FFH 6)AND DX,0H 7)TEST DX,80H 8)TEST DX,01H
3.15 試寫出移位指令執(zhí)行后BX寄存器的內(nèi)容,執(zhí)行前(BX)=6CB5H,CF=0。
1)MOV CL,04H SHR BX,CL 2)MOV CL,03H SAL BX,CL 3)ROR BX,1 4)MOV CL,06H RCR BX,CL
3.16 若(AX)=0012H,(BX)=0034H,則下列指令執(zhí)行后AX為多少?
MOV CL,8 ROL AX,CL ADD AX,BX
3.17 試分析下面的程序段所完成的功能。
MOV CL,4 SHL DX,CL MOV BL,AH SHL AX,CL SHR BL,CL OR DL,BL
3.18 下列程序段執(zhí)行后(AL)=?(DL)=?完成的是什么功能?
MOV CL,4 MOV AL,48H MOV DL,AL AND AL,0FH OR AL,30H SHR DL,CL OR DL,30H
3.19 編寫程序使:
1)BX寄存器低4位置1
2)AX寄存器的低4位清0
3)AX寄存器各位取反
4)CX寄存器的低4位取反
5)用TEST指令測(cè)試AL寄存器的位1、位5和位7是否同時(shí)為1,如果是則把0FFH送CL寄存器,否則將0送CL寄存器。
6)將AH的低4位與AL的低4位拼成一個(gè)字節(jié)(AH的低4位為拼裝后的高4位),結(jié)果送AH中。
3.20 說明80386的32位通用寄存器與16位通用寄存器這間的關(guān)系。
3.21 80386的尋址方式有何特點(diǎn)。
3.22 設(shè)AX中有一有符號(hào)數(shù),請(qǐng)用兩條不同的指令將AX中的值擴(kuò)展到EAX中。
3.23 請(qǐng)用兩條不同的指令使BX所指的32位存儲(chǔ)器操作數(shù)的第20取反。
3.24 用一條指令實(shí)現(xiàn)把EAX中的32位數(shù)保存到寄存器對(duì)DX:AX中。
3.25 設(shè)寄存器對(duì)EDX:EAX中放有0102030405060708H,請(qǐng)寫出指令使其中的內(nèi)容成為0807060504030201H。
3.26 試給出下列指令序列執(zhí)行后目的寄存器的內(nèi)容。
1)MOV BX,-10H MOVSX EBX,BX 2)MOV DL,-37H MOVSX ECX,DL 3)MOV AX,37H MOVZX ECX,AX 4)MOV CL,0A3H MOVZX EAX,CL
3.27 編寫程序段,將EBX、ECX和ESI寄存器的內(nèi)容相加,其和存入EDI寄存器中(不考慮溢出)。
- Advanced Quantitative Finance with C++
- Microsoft Application Virtualization Cookbook
- Vue.js 2 and Bootstrap 4 Web Development
- Web Scraping with Python
- CentOS 7 Server Deployment Cookbook
- Apache Spark 2 for Beginners
- Programming ArcGIS 10.1 with Python Cookbook
- 數(shù)據(jù)結(jié)構(gòu)習(xí)題精解(C語言實(shí)現(xiàn)+微課視頻)
- Learn WebAssembly
- OpenShift在企業(yè)中的實(shí)踐:PaaS DevOps微服務(wù)(第2版)
- SSM輕量級(jí)框架應(yīng)用實(shí)戰(zhàn)
- C程序設(shè)計(jì)案例教程
- 移動(dòng)互聯(lián)網(wǎng)軟件開發(fā)實(shí)驗(yàn)指導(dǎo)
- Python:Deeper Insights into Machine Learning
- Data Science Algorithms in a Week