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