?? 匯005.txt
字號(hào):
了解的內(nèi)容:指令的執(zhí)行周期,以便選擇較快的指令來(lái)完成同樣的功能。
掌握的內(nèi)容:常用指令對(duì)各標(biāo)志位的影響。
熟練掌握的內(nèi)容:各種指令的功能、特殊要求(注意事項(xiàng))和隱含操作數(shù)。
建議學(xué)習(xí)時(shí)間:20小時(shí)。
注意:不要求一定要先學(xué)完本章中的所有指令才能看后面章節(jié)的內(nèi)容。
在學(xué)習(xí)并掌握了一些常用的指令后,即可閱讀本章以后的有關(guān)內(nèi)容。在遇到?jīng)]學(xué)過(guò)的指令時(shí),可返回來(lái)閱讀本章中該指令的內(nèi)容。第5章 微機(jī)CPU的指令系統(tǒng)
指令系統(tǒng)確定了CPU所能完成的功能,是用匯編語(yǔ)言進(jìn)行程序設(shè)計(jì)的最基本部分。如果不熟悉匯編指令的功能及其有關(guān)規(guī)定,那么,肯定不能靈活運(yùn)用匯編語(yǔ)言。所以,本章的內(nèi)容是學(xué)習(xí)本課程的重點(diǎn)和難點(diǎn)。
5.1 匯編語(yǔ)言指令格式
為了介紹指令系統(tǒng)中指令的功能,先要清楚匯編語(yǔ)言是如何書寫指令的,這就象在學(xué)習(xí)高級(jí)語(yǔ)言程序設(shè)計(jì)時(shí),要清楚高級(jí)語(yǔ)言語(yǔ)句的語(yǔ)義、語(yǔ)法及其相關(guān)規(guī)定一樣。
5.1.1 指令格式
匯編語(yǔ)言的指令格式如下:
指令助憶符 [操作數(shù)1 [, 操作數(shù)2 [, 操作數(shù)3]]] [;注釋]
指令助憶符體現(xiàn)該指令的功能,它對(duì)應(yīng)一條二進(jìn)制編碼的機(jī)器指令。指令的操作數(shù)個(gè)數(shù)由該指令的確定,可以沒(méi)有操作數(shù),也可以有一個(gè)、二個(gè)或三個(gè)操作數(shù)。絕大多數(shù)指令的操作數(shù)要顯式的寫出來(lái),但也有指令的操作數(shù)是隱含的,不需要在指令中寫出。
當(dāng)指令含有操作數(shù),并要求在指令中顯式地寫出來(lái)時(shí),則在書寫時(shí)必須遵守:
指令助憶符和操作數(shù)之間要有分隔符,分隔符可以是若干個(gè)空格或TAB鍵;
如果指令含有多個(gè)操作數(shù),那么,操作數(shù)之間要用逗號(hào)","分開。
指令后面還可以書寫注釋內(nèi)容,不過(guò),要在注釋之前書寫分號(hào)";"。
5.1.2 了解指令的幾個(gè)方面
在學(xué)習(xí)匯編指令時(shí),指令的功能無(wú)疑是我們學(xué)習(xí)和掌握的重點(diǎn),但要準(zhǔn)確、有效地運(yùn)用這些指令,我們還要熟悉系統(tǒng)對(duì)每條指令的一些規(guī)定或約束。
歸納起來(lái),對(duì)指令還要掌握以下幾個(gè)方面內(nèi)容:
、要求指令操作數(shù)的尋址方式;
、指令對(duì)標(biāo)志位的影響、標(biāo)志位對(duì)指令的影響;
、指令的執(zhí)行時(shí)間,對(duì)可完成同樣功能的指令,要選用執(zhí)行時(shí)間短的指令(見附錄2)。
5.2、指令系統(tǒng)
指令系統(tǒng)是CPU指令的集合,CPU除了具有計(jì)算功能的指令外,還有實(shí)現(xiàn)其它功能的指令,也有為某種特殊的應(yīng)用而增設(shè)的指令。
通常,把指令按其功能分成以下幾大類:
數(shù)據(jù)傳送指令
標(biāo)志位操作指令
算術(shù)運(yùn)算指令
邏輯運(yùn)算指令
移位操作指令
位操作指令
比較運(yùn)算指令
下面,我們逐一介紹每類指令中的指令。
循環(huán)指令
轉(zhuǎn)移指令
條件設(shè)置字節(jié)指令
字符串操作指令
ASCII-BCD碼運(yùn)算調(diào)整指令
處理器指令
5.2.1 數(shù)據(jù)傳送指令
數(shù)據(jù)傳送指令又分為:傳送指令、交換指令、地址傳送指令、堆棧操作指令、轉(zhuǎn)換指令和I/O指令等。
除了標(biāo)志位操作指令SAHF和POPF指令外,本類的其它指令都不影響標(biāo)志位。
1、傳送指令MOV(Move Instruction)
傳送指令是使用最頻繁的指令,它相對(duì)于高級(jí)語(yǔ)言里的賦值語(yǔ)句。指令的格式如下:
MOV Reg/Mem, Reg/Mem/Imm
其中:Reg—Register(寄存器),Mem—Memory(存儲(chǔ)器),Imm—Immediate(立即數(shù)),它們可以是8位、16位或32位(特別指出其位數(shù)的除外)。在本網(wǎng)絡(luò)課件的網(wǎng)頁(yè)中,都將采用上述縮寫,此后不再說(shuō)明。
指令的功能是把源操作數(shù)(第二操作數(shù))的值傳給目的操作數(shù)(第一操作數(shù))。指令執(zhí)行后,目的操作數(shù)的值被改變,而源操作數(shù)的值不變。在存儲(chǔ)單元是該指令的一個(gè)操作數(shù)時(shí),該操作數(shù)的尋址方式可以是任意一種存儲(chǔ)單元尋址方式。
下面列舉幾組正確的指令例子:
源操作數(shù)是寄存器
MOV CH, AL MOV BP, SP MOV ECX, EBX
MOV DS, AX MOV [BX], CH MOV [BX+SI], AX
源操作數(shù)是存儲(chǔ)單元
MOV AL, [100H] MOV BX, ES:[DI] MOV EDX, [BX]
MOV BX, VARW MOV AX, [BX+SI] MOV CH, [BX+DI+100H]
其中:VARW是字類型內(nèi)存變量(下同)。
源操作數(shù)是立即數(shù)
MOV AL, 89H MOV BX, -100H MOV EDX, 12345678H
MOV VARW, 200H MOV [BX], 2345H MOV [BX+DI], 1234H
在匯編語(yǔ)言中,主要的數(shù)據(jù)傳送方式如圖5.1所示。雖然一條MOV指令能實(shí)現(xiàn)其中大多數(shù)的數(shù)據(jù)傳送方式,但也存在MOV指令不能實(shí)現(xiàn)的傳送方式。
圖5.1 MOV指令數(shù)據(jù)傳送示意圖
對(duì)MOV指令有以下幾條具體規(guī)定,其中有些規(guī)定對(duì)其它指令也同樣有效。
1)、兩個(gè)操作數(shù)的數(shù)據(jù)類型要相同,要同為8位、16位或32位;如:MOV BL, AX等是不正確的;
2)、兩個(gè)操作數(shù)不能同時(shí)為段寄存器,如:MOV ES, DS等;
3)、代碼段寄存器CS不能為目的操作數(shù),但可作為源操作數(shù),如:指令MOV CS, AX等不正確,但指令MOV AX, CS等是正確的;
4)、立即數(shù)不能直接傳給段寄存器,如:MOV DS, 100H等;
5)、立即數(shù)不能作為目的操作數(shù),如:MOV 100H, AX等;
6)、指令指針I(yè)P,不能作為MOV指令的操作數(shù);
7)、兩個(gè)操作數(shù)不能同時(shí)為存儲(chǔ)單元,如:MOV VARA, VARB等,其中VARA和VARB是同數(shù)據(jù)類型的內(nèi)存變量。
對(duì)于規(guī)定2、4和7,我們可以用通用寄存器作為中轉(zhuǎn)來(lái)達(dá)到最終目的。表5.1列舉一個(gè)可行的解決方案,盡供參考。讀者可考慮用其它辦法來(lái)完成同樣的功能。
表5.1 MOV指令的變通方法
功能描述
不正確的指令
可選的解決方法
把DS的值傳送給ES
MOV ES, DS
MOV AX, DS
MOV ES, AX
把100H傳給DS
MOV DS, 100H
MOV AX, 100H
MOV DS, AX
把字變量VARB的值傳送給字變量VARA
MOV VARA, VARB
MOV AX, VARB
MOV VARA, AX
對(duì)于情況1:不同位數(shù)數(shù)據(jù)之間的傳送問(wèn)題,在80386及其以后的CPU中,增加一組新的指令——傳送-填充指令,它可把位數(shù)少的源操作數(shù)傳送給位數(shù)多的目的操作數(shù),多出的部分按指令的規(guī)定進(jìn)行填充。
2、傳送—填充指令(Move-and-Fill Instruction)
傳送—填充指令是把位數(shù)短的源操作數(shù)傳送給位數(shù)長(zhǎng)的目的操作數(shù)。指令格式如下:
MOVSX/MOVZX Reg/Mem, Reg/Mem/Imm ;80386+
其中:80386+表示80386及其之后的CPU,其它類似符號(hào)含義類同,不再說(shuō)明。
指令的主要功能和限制與MOV指令類似,不同之處是:在傳送時(shí),對(duì)目的操作數(shù)的高位進(jìn)行填充。根據(jù)其填充方式,又分為:符號(hào)填充和零填充。
傳送—填充指令的功能如圖5.2所示。
(a). MOVSX的執(zhí)行效果
(b). MOVZX的執(zhí)行效果
圖5.2 傳送—填充指令執(zhí)行過(guò)程示意圖
、符號(hào)填充指令MOVSX(Move with Sign-Extend)
MOVSX的填充方式是:用源操作數(shù)的符號(hào)位來(lái)填充目的操作數(shù)的高位數(shù)據(jù)位。
、零填充指令MOVZX(Move with Zero-Extend)
MOVZX的填充方式是:恒用0來(lái)填充目的操作數(shù)的高位數(shù)據(jù)位。
例5.1 已知:AL=87H,指令MOVSX CX, AL,MOVZX DX, AL執(zhí)行后,問(wèn)CX和DX的值是什么?
解:根據(jù)傳送-填充指令的填充方式可知:
指令MOVSX CX, AL執(zhí)行后,(CX)=0FF87H,指令MOVZX DX, AL執(zhí)行后,(DX)=0087H。
從上例可看出,兩條指令的源操作數(shù)完全一樣,但因?yàn)樗鼈兊奶畛浞绞讲煌玫降慕Y(jié)果而就不同。
試比較下列指令,分析它們執(zhí)行結(jié)果的相同和不同之處:
MOV AX, 87H MOVSX AX, 87H MOVZX AX, 87H
3、交換指令XCHG(Exchange Instruction)
交換指令XCHG是兩個(gè)寄存器,寄存器和內(nèi)存變量之間內(nèi)容的交換指令,兩個(gè)操作數(shù)的數(shù)據(jù)類型要相同。其指令格式如下:
XCHG Reg/Mem, Reg/Mem
該指令的功能和MOV指令不同,后者是一個(gè)操作數(shù)的內(nèi)容被修改,而前者是兩個(gè)操作數(shù)都會(huì)發(fā)生改變。寄存器不能是段寄存器,兩個(gè)操作數(shù)也不能同時(shí)為內(nèi)存變量。
XCHG指令的功能如圖5.3所示。
圖5.3 XCHG指令的執(zhí)行功能示意圖
例5.2 已知:AX=5678H,BX=1234H,指令XCHG AX, BX執(zhí)行后,AX和BX的值是什么?
解:這是兩個(gè)寄存器內(nèi)容進(jìn)行交換,指令執(zhí)行后,有:(AX)=1234H,(BX)=5678H。
4、取有效地址指令LEA(Load Effective Address)
指令LEA是把一個(gè)內(nèi)存變量的有效地址送給指定的寄存器。其指令格式如下:
LEA Reg, Mem
該指令通常用來(lái)對(duì)指針或變址寄存器BX、DI或SI等置初值之用。其功能如右圖所示。
例如:
圖5.4 LEA指令的功能示意圖
…
BUFFER DB 100 DUP(?)
…
LEA BX, BUFFER ;把字節(jié)變量BUFFER在數(shù)據(jù)段內(nèi)的偏移量送給BX
…
問(wèn)題:指令“LEA BX BUFFER”和“MOV BX, OFFSET BUFFER”的執(zhí)行效果是一樣的嗎?指令“LEA BX,[BX+200]”和“MOV BX,OFFSET [BX+200]”二者都正確嗎?
5、取段寄存器指令(Load Segment Instruction)
該組指令的功能是把內(nèi)存單元的一個(gè)“低字”傳送給指令中指定的16位寄存器,把隨后的一個(gè)“高字”傳給相應(yīng)的段寄存器(DS、ES、FS、GS和SS)。其指令格式如下:
LDS/LES/LFS/LGS/LSS Reg, Mem
指令LDS(Load Data Segment Register)和LES(Load Extra Segment Register)在8086CPU中就存在,而LFS和LGS(Load Extra Segment Register)、LSS(Load Stack Segment Register)是80386及其以后CPU中才有的指令。
若Reg是16位寄存器,那么,Men必須是32位指針;若Reg是32位寄存器,那么,Men必須是48位指針,其低32位給指令中指定的寄存器,高16位給指令中的段寄存器。指令的執(zhí)行結(jié)果如圖5.5所示。
(a) 32位指針
(b) 48位指針
圖5.5、LDS指令的執(zhí)行步驟示意圖
例如:
…
POINTER DD 12345678H
…
LDS BX, POINTER
…
指令的執(zhí)行結(jié)果如圖5.5所示。各寄存器的內(nèi)容分別為:(BX)=5678H,(DS)=1234H。
下面控件是學(xué)習(xí)和掌握MOV、MOVSX/MOVZX、XCHG、LEA、LDS/LES/LFS/LGS/LSS指令的,它可檢查用戶輸入這些指令的合法性,并對(duì)合法的指令顯示其執(zhí)行的結(jié)果。
注意:如果指令中含有表示內(nèi)存單元的尋址方式,那么其控件中的"內(nèi)存單元的類型"即表示該指令中內(nèi)存單元的數(shù)據(jù)類型。
6、堆棧操作指令(Stack Operation Instruction)
堆棧是一個(gè)重要的數(shù)據(jù)結(jié)構(gòu),它具有“先進(jìn)后出”的特點(diǎn),通常用來(lái)保存程序的返回地址。它主要有兩大類操作:進(jìn)棧操作和出棧操作。
1)、進(jìn)棧操作
、PUSH(Push Word or Doubleword onto Stack)
指令格式:PUSH Reg/Mem
PUSH Imm ;80286+
一個(gè)字進(jìn)棧,系統(tǒng)自動(dòng)完成兩步操作:SP←SP-2,(SP)←操作數(shù);
一個(gè)雙字進(jìn)棧,系統(tǒng)自動(dòng)完成兩步操作:ESP←ESP-4,(ESP)←操作數(shù)。
、PUSHA(Push All General Registers)
指令格式:PUSHA ;80286+
其功能是依次把寄存器AX、CX、DX、BX、SP、BP、SI和DI等壓棧。
、PUSHAD(Push All 32-bit General Registers)
指令格式:PUSHAD ;80386+
其功能是把寄存器EAX、ECX、EDX、EBX、ESP、EBP、ESI和EDI等壓棧。
2)、出棧操作
、POP(Pop Word or Doubleword off Stack)
指令格式:POP Reg/Mem
彈出一個(gè)字,系統(tǒng)自動(dòng)完成兩步操作:操作數(shù)←(SP),SP←SP-2;
彈出一個(gè)雙字,系統(tǒng)自動(dòng)完成兩步操作:操作數(shù)←(ESP),ESP←ESP-4。
、POPA(Pop All General Registers)
指令格式:POPA ;80286+
其功能是依次把寄存器DI、SI、BP、SP、BX、DX、CX和AX等彈出棧。其實(shí),程序員不用記住它們的具體順序,只要與指令PUSHA對(duì)稱使用就可以了。
、POPAD(Pop All 32-bit General Registers)
指令格式:POPAD ;80386+
其功能是依次把寄存器EDI、ESI、EBP、ESP、EBX、EDX、ECX和EAX等彈出棧,它與PUSHAD對(duì)稱使用即可。
7、轉(zhuǎn)換指令XLAT(Translate Instruction)
轉(zhuǎn)換指令有兩個(gè)隱含操作數(shù)BX和AL。指令格式如下:
XLAT/XLATB
其功能是把BX的值作為內(nèi)存字節(jié)數(shù)組首地址、下標(biāo)為AL的數(shù)組元素的值傳送給AL。其功能描述的表達(dá)式是:AL←BX[AL],其功能示意圖如圖5.6所示。
圖5.6 XLAT/XLATB指令的功能示意圖
8、I/O指令
有關(guān)I/O指令將在第8.1.2節(jié)——I/O指令——中介紹,在此從略。
5.2.2 標(biāo)志位操作指令
標(biāo)志位操作指令是一組對(duì)標(biāo)志位置位、復(fù)位、保存和恢復(fù)等操作的指令。
1、進(jìn)位CF操作指令
、清進(jìn)位指令CLC(Clear Carry Flag):CF←0
、置進(jìn)位指令STC(Set Carry Flag):CF←1
、進(jìn)位取反指令CMC(Complement Carry Flag):CF←not CF
2、方向位DF操作指令
、清方向位指令CLD(Clear Direction Flag):DF←0
、置方向位指令STD(Set Direction Flag):DF←1
3、中斷允許位IF操作指令
、清中斷允許位指令CLI(Clear Interrupt Flag):IF←0
其功能是不允許可屏蔽的外部中斷來(lái)中斷其后程序段的執(zhí)行。
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -