|
在接下來的四篇里將介紹80386的匯編指令及用法,并和8086的指令進行比較。
80386的指令集包含了8086/8088,80186,80286的指令集,可以分為幾個大類:數(shù)據(jù)傳送指令,算術(shù)運算/邏輯運算指令,移位指令,控制轉(zhuǎn)移指令,串操作指令,高級語言支持的指令,條件字節(jié)設(shè)置指令,位操作指令,處理器控制指令和保護方式指令。高級語言支持指令始于80186,保護方式指令始于80286,條件字節(jié)設(shè)置指令和位操作指令是80386新增的。 本篇主要介紹數(shù)據(jù)傳送指令,數(shù)據(jù)傳送指令可以分為:通用數(shù)據(jù)傳送,累加器專用傳送,地址傳送,標志傳送,分別介紹如下: A.數(shù)值傳送指令MOV,MOVZX,MOVSX,XCHG,PUSH,PUSHA,PUSHAD,POPA,POPAD, a.MOV,指令和8086相似,不過它支持32位操作。 b.MOVZX,零擴展傳送,格式--MOVZX DST,SRC,表示將源操作送給目的操作數(shù),目的操作數(shù)空出的部分用0填補。 c.MOVSX,符號擴展傳送,格式--MOVSX DST,SRC,表示將源操作送給目的操作數(shù),目的操作數(shù)空出的部分用SRC的符號位來填補,舉個簡單的例子來演示: MOV DL,90H; MOVSX AX,DL;AX=FF90H MOVZX AX,DL;AX=0090H MOVSX ESI,DL;ESI=FFFFFF90H MOVZX ESI,DL;ESI=00000090H 事實上在8086中也有兩條指令CBW,CWD可以對操作數(shù)進行擴展。MOVSX可以對有符號數(shù)進行擴展,MOVZX可以對無符號數(shù)進行擴展,看看CBW,CWD的用法: CBW將字節(jié)數(shù)據(jù)擴展成字,符號位擴展到AH中 CWD將字數(shù)據(jù)擴展成雙字,符號位放到DX中 MOV AL,70H; CBW;//AX=0070 CWD;//DX=0000,AX=0070 d.XCHG,功能和8080相同,不過它支持8位,16位,32位操作,下面的語句均是合法的。 XCHG AH,AL XCHG AX,AL XCHG ESI,EDI XCHG ESI,[EBX+EDI+1000H] e.PUSH,和8086不同的是,它支持立即數(shù)入棧,8位入棧,當然還有32位入棧,下面的語句均是合法的。 PUSH AL PUSH BH PUSH 100H PUSH EAX PUSH EBX PUSH DWORD PTR [EAX] f.POP,功能和用法和8086一樣。 g.PUSHA,將8個通用寄存器全部進棧,進棧順序為:AX,CX,DX,BX,SP,BP,SI,DI,然后SP指針寄存減16,不過SP入棧的內(nèi)容是PUSHA指令執(zhí)行前的內(nèi)容。 h.POPA,8個通用寄存器全部出棧,堆棧指針寄存器不是堆棧中彈出的內(nèi)容,而是加16而得到的,雖然這樣得到的值和從堆棧中彈出來的內(nèi)容一樣,但物理意義不一樣。 i.PUSHAD,將8個32位通用寄存器全部入棧,入棧順序EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI,ESP的內(nèi)容是執(zhí)行指令PUSHAD之前的內(nèi)容 j.POPAD,8個32位通寄存器全部出棧,ESP的內(nèi)容參見h B.地址傳送指令LEA,LDS,LES,LFS,LGS,LSS a.LEA,取有效地址,功能,用法與8086相同,不過它支持32位操作。規(guī)則:目的操作必須是16位或32位通用寄存器,當目的操作數(shù)是16位時,那么只裝入有效地址的低16位。事實上LEA指令相當于偽指令OFFSET,看例子: MOV EAX,12345678H MOV EBX,56784321H LEA ECX,[EAX+EBX];ECX=99999999H b.LDS,裝入指針,功能,用法與8086相同,不過它支持32位操作。格式:LDS REG,OPRD。規(guī)則,目的寄存器必須是16位或32位的通用寄存器,OPRD必須是內(nèi)存單元,不可以是立即數(shù)。如果目的寄存器是16位,那么源操作數(shù)OPRD含32位指針;如果目的寄存器是32位,那么源操作數(shù)有48位指針。該指令將目的操作數(shù)OPRD所指向的內(nèi)存單存的4個或6個連續(xù)字節(jié)的內(nèi)容送給助記符指令中指定的DS段寄存器和指令中目的寄存器。比如: LDS EAX,[1000H];這表明將偏移地址為1000,1001H這兩個字節(jié)單元的內(nèi)容送給段寄存器DS,將偏移地址1002,1003,1004,1005四個字節(jié)單元的內(nèi)容送往EAX。 LDS AX,[1000H];這表明將偏移地址為1000,1001H這兩個字節(jié)單元的內(nèi)容送給段寄存器DS,將偏移地址1002,1003H兩個字節(jié)單元的內(nèi)容送往EAX。 c.LES,同LDS,不過段寄存器是ES。 d.LFS,同LDS,不過段寄存器是FS。 e.LGS,同LDS,不過段寄存器是GS。 h.LSS,同LDS,不過段寄存器是SS。 C.標志傳送指令LAHF,SAHF,PUSHF,PUSHFD,POPF,POPFD a.LAHF,將標志寄存器的低8位送至AH中,包括SF,ZF,ZF,PF,CF。 b.SAHF,與i的過程恰好相反 c.PUSHF,將標志寄存器的EFLAGS低16位內(nèi)容入棧,和8086相同 d.PUSHFD,將標志寄存器EFLAGS的內(nèi)容入棧 e.POPF,將棧頂?shù)囊粋€字彈出,并將它送到標志寄存器EFLAGS的低16位 f.POPFD,將棧頂?shù)膬蓚€字彈出,并將它送到標志寄存器EFLAGS D.累加器傳送指令I(lǐng)N,OUT,XLAT a.IN,和8086相同,但可以輸入一個雙字節(jié),同樣如果端口的范圍位于00H-FFH,可以直接用,如果超出這個范圍,則先要將端口號送至DX,下面的語句是合法的: IN AL,20H;從20H端口讀入一個字節(jié) IN AX,20H;從20H端口讀入一個字 MOV DX,0378H IN EAX,DX;從20H端口讀兩個字節(jié) b.OUT,和8086相同,但可以輸出一個雙字節(jié),同樣如果端口的范圍位于00H-FFH,可以直接用,如果超出這個范圍,則先要將端口號送至DX,下面的語句是合法的: OUT 20H,AL;從20H端口輸出一個字節(jié) IN 20H,AX;從20H端口輸出一個字 MOV DX,0378H IN EAX,DX;從20H端口輸出兩個字 c.XLAT,查表指令,功能和用法與8086相同,不過基址寄存器用的是EBX,來看看XLAT的實現(xiàn)過程:XLAT以BX作為基址寄存器,以AL作為變址寄存進器對指定的緩沖區(qū)進行查表,將AL指定位置的內(nèi)容送往AL,比如說我們在MS-DOS方式寫一個小程序: C:\>Debug -A100 MOV BX,0120 SUB AL,AL MOV DL,AL MOV AH,2 INT 21 MOV AH,4C INT 21 INT 20 -E120 ‘ABCDEFGHIJKLLMMDDKDJDK‘ =G100 屏幕上會顯示A,如果AL=3,那么屏幕會顯示D 以上所有的指令均不影響EFLAGS的各標志位。 |
|
|