汇编学习笔记(3)-80x86指令集
前言
(1)指令的一般格式
[標(biāo)號(hào):] 助記符 [操作數(shù)1 , [操作數(shù)2]] [; 注釋]
一行一條指令
助記符就是指令的名稱,每條指定必定有個(gè)助記符。 助記符前面的標(biāo)號(hào)是給匯編編譯器看的,由我們自己取名,一般取表示本段功能的相關(guān)的名字,對(duì)編譯器而言表示的是指令的地址。
每個(gè)指令根據(jù)指令作用的不同會(huì)帶有一個(gè)或者兩個(gè)操作數(shù),如果有兩個(gè)操作數(shù),則操作數(shù)中間用 ?逗號(hào)","? 隔開。?;之后到本行結(jié)束為注釋 是寫個(gè)我們自己看的內(nèi)容,用于描述指令的功能,方便理解程序功能。編譯器會(huì)將注釋內(nèi)容直接舍棄。?
注意: 每條指令都會(huì)有一些使用限制,有些限制可能是適用于所有指令的,我會(huì)盡量用相同的顏色標(biāo)記出相同的限制。
?
(2)全局規(guī)則:
源操作數(shù)和目的操作數(shù)類型要保持一致,要么都是字,要么都是字節(jié)
除了串操作指令,源操作數(shù)和目的操作數(shù)不能同時(shí)為 內(nèi)存單元(可以使用其他寄存器中轉(zhuǎn))
? ?段寄存器之間數(shù)據(jù)不能互相傳遞
cs段寄存器只能用專門的指令來操作
?
(3)指令集分類
根據(jù)指令集的功能大致可分為六類:
(1) 數(shù)據(jù)傳送
MOV; ?XCHG;??LEA; ??LDS; ?LES; ?PUSH; ?POP; ?
(2) 算數(shù)運(yùn)算
ADD;??ADC; ?INC;?SUB; ?SBB; ?DEC; ?NEG; ?CMP;?MUL; ?IMUL; ?DIV; ?IDIV; ?CBW; ?CWD;
(3) 邏輯運(yùn)算
NOT; ?AND; ?OR; ?XOR;?TEST;?SAL; ?SHL; ?SAR;SHR;?ROL;?ROR;?RCL;?RCR;
(4) 串操作
(5) 程序控制
JMP; ? JC; ? JNC; ? JP; ?JPE; ? JA; ?JNBE; ?JAE; ?JNB; ?JB; ?JNAE; ?JE; ?JZ; ?JNZ; ?JNEL; ?JO; ?JNO; ?JS; ?JNS; ?JG; ?JNLE; ?JGE; ?JNL; ?JL; ?JNGE; ?JLE; ?JNG; ?JCXZ; ?LOOP; ?LOOPE; ?LOOPZ; ?LOOPNE ?;LOOPNZ; ?JCXZ;
(6) CPU控制(標(biāo)志位控制)
? LAHF; ?SAHF; ?PUSHF; ?POPF; ?CLC; ?STC; ?CMC; ?CLD; ?STD; ?CLI; ?STI;
?
數(shù)據(jù)傳送指令
1. 數(shù)據(jù)傳送 MOV
MOV DST, SRC
這條指令上面已經(jīng)用過很多次了,作用就是將SRC的數(shù)據(jù)復(fù)制到DST,指令本身不會(huì)對(duì)SRC的數(shù)據(jù)做任何的修改。
限制:
源操作數(shù)可以是寄存器,累加器,內(nèi)存單元,立即數(shù) ?目的操作數(shù)可以是寄存器,累加器,內(nèi)存單元
源和目的不能同時(shí)是段寄存器
代碼段寄存器CS 不能作為目的
指令指針寄存器不能作為源,也不能作為目的寄存器
立即數(shù)不能直接傳送到段寄存器,立即數(shù)永遠(yuǎn)不能作為目的操作數(shù)
?
2. 交換指令?XCHG?
XCHG VALUE1, VALUE2
這條指令交換兩個(gè)數(shù)值。
限制
兩個(gè)操作數(shù)不能有段寄存器,也不能同時(shí)是內(nèi)存單元
不能有立即數(shù)
?
3.地址傳送指令
? (1) LEA指令 (Load Effective Address)
LEA REG, OPRD
該指令的作用是將操作數(shù)OPRG的地址傳送到REG寄存器中,和MOV有本質(zhì)區(qū)別,MOV是將操作數(shù)OPRG的內(nèi)容傳送到寄存器,所以LEA的源操作數(shù)一定是內(nèi)存,目的操作數(shù)一定是16位寄存器
限制:
OPRG 必須是內(nèi)存地址
REG 必須是16位通用寄存器
?
(2) LDS指令 (Load pointer into DS)
LDS REG, OPRD
這個(gè)指令是LEA的 高級(jí)版本,傳送的是32位地址,指令會(huì)將段地址存儲(chǔ)到DS寄存器,而偏移部分則存儲(chǔ)到REG寄存器中。
限制:
REG可以16位通用寄存器,或者指針寄存器(sp bp,IP不可以)和變址寄存器(SI DI),但是一般都是變址寄存器
OPRD 必須是32位地址
?
(3) LES指令 (Load pointer into ES)
LES REG, OPRD
和LDS是一模一樣的,唯一的區(qū)別就是段地址存儲(chǔ)到ES寄存器中
?
4.堆棧操作指令
堆棧是用來存儲(chǔ)臨時(shí)數(shù)據(jù)的一段內(nèi)存,由SS和SP兩個(gè)寄存器定義, SS 定義了堆棧的基礎(chǔ)地址,SP定義了堆棧的當(dāng)前位置,如下圖所示
?
?SS 在低地址,SP在高地址,有數(shù)據(jù)入棧之后SP就向上移動(dòng),當(dāng)SP和SS移動(dòng)到一個(gè)位置的時(shí)候即表示堆棧滿了,所以SS定義堆棧地址,SP定義堆棧大小,因此堆棧的方向是向低地址方向生長(zhǎng)的,先入棧的數(shù)據(jù)地址反而高。在這種機(jī)制下也存在一個(gè)問題,就是出棧的時(shí)候就沒有一個(gè)限制了。應(yīng)為SP到哪里才算是堆棧空了? 所以使用的時(shí)候要當(dāng)心。
用途:
現(xiàn)場(chǎng)和返回地址的保護(hù)
寄存器內(nèi)容的保護(hù)
傳遞參數(shù)
存儲(chǔ)局部變量
?
入棧指令 PUSH
PUSH SRC
該指令將源操作數(shù)SRC壓入棧中,他先將SP指針減2,然后將SRC存入SP所指位置。
? ?SRC可以是通用寄存器也可以是段寄存器也可以是內(nèi)存單元。數(shù)據(jù)存儲(chǔ)入棧的時(shí)候16位數(shù)據(jù)高字節(jié)存儲(chǔ)在高地址,低字節(jié)存儲(chǔ)在低地址。
?
? 出棧指令 POP
?POP DST
將棧頂數(shù)據(jù)傳送到DST中,DST可以是通用寄存器,段寄存器(除CS)也可以是內(nèi)存單元
?
?
算數(shù)運(yùn)算指令
基本規(guī)則
加減運(yùn)算對(duì) 有符號(hào)數(shù)和無符號(hào)數(shù)是一視同仁的,意思就是對(duì)數(shù)據(jù)的加減運(yùn)算,他會(huì)同時(shí)認(rèn)為是無符號(hào)運(yùn)算而影響CF AF標(biāo)志位,并同時(shí)認(rèn)為是有符號(hào)運(yùn)算而影響OF SF標(biāo)志位。
只有通用寄存器和內(nèi)存單元可以存放計(jì)算結(jié)果。兩個(gè)操作數(shù)中不能同時(shí)是內(nèi)存單元。
如果有兩個(gè)操作數(shù),類型必須一致。
?
1.?加法指令
(1)普通加法指令 ADD
ADD OPD1, OPD2
這條指令完成功能是 將OPD1 和 OPD2 的內(nèi)容相加存儲(chǔ)到OPD1中,C代碼表示的話就是 OPD1 = OPD1 + OPD2
(2)帶進(jìn)位加指令 ADC
ADC OPD1, OPD2
?這條指令完成功能是 將OPD1 + OPD2 + 進(jìn)位標(biāo)志CF 的結(jié)果相加存儲(chǔ)到OPD1中,C代碼表示的話就是 OPD1 = OPD1 + OPD2 +CF
?
(3)加1指令 INC
INC OPD
這條指令的功能等效于 ADD OPD , 1,這條指令不影響
簡(jiǎn)單解釋下加法命令對(duì)標(biāo)志位的影響
比如指令組
MOV AX 7896H ? ? ?; ? AH = 78H ?AL= 96H,對(duì)各標(biāo)志位無影響
? ?ADD AL, AH ; ? AL = AL + AH, ? ? AL(10EH) = 96H + 78H, 而進(jìn)制就是 ?0001 0000 1110 = 1001 0110 + 0111 1000
; 這里注意 AL=0E, 應(yīng)為AL只能保存8位所以最高位的1 被舍棄了,AL=?0000 1110
; 顯然結(jié)果也不為0 所以ZF = 0
; 結(jié)果中1的位數(shù)是奇數(shù) PF = 0
; ?首先按照無符號(hào)數(shù)相加 這里很明顯的 最高位進(jìn)位了所以 CF =1
; 然后看AF寄存器 0110 + 1000 = 1110 也是很明顯的沒有發(fā)生進(jìn)位所以 AF =0
; 然后看有符號(hào)數(shù)計(jì)算怎么算按照有符號(hào)數(shù)的話 96H 由于最高位是1 所以就是負(fù)數(shù)了 表示的值就是 -6A,注意CPU認(rèn)為數(shù)據(jù)都是補(bǔ)碼形式保存。
; 實(shí)際的計(jì)算是?AL(0EH) = -6AH + 78H,這就是設(shè)計(jì)的巧妙了,無論是按照有符號(hào)還是無符號(hào),二進(jìn)制結(jié)果都是一樣的。
; ? ?首先看SF 顯然數(shù)據(jù)是正數(shù) 所以 SF =0
; ? 再看OF 數(shù)據(jù)也沒超過表示范圍 OF =0
?
2.減法指令
(1)普通減法指令 SUB
SUB OPD1, OPD2
這套指令完成的功能就是 將 OPD1 -OPD2的結(jié)果存儲(chǔ)到 OPD1中, C代碼表示就是OPD1=OPD1-OPD2
?
(2)帶借位減法指令 SBB
SBB OPD1, OPD2
這套指令的功能就是 將 OPD1 -OPD2 - CF的內(nèi)容保存到OPD1中,C代碼表示就是OPD1 = OPD1 -OPD2 -1
?
(3)減1指令 DEC
DEC OPD
等效于 SUB OPD1 , 1
?
(4)取補(bǔ)指令 NEG
NEG OPD
這條指令的作用 將 0-OPD 的結(jié)果存儲(chǔ)到 OPD中,C代碼表示就是 OPD = 0 - OPD
?
(5)比較指令 CMP
CMP OPRD1, OPRD2
這條指令的作用是OPRD1-OPRD2 結(jié)果不保存,但是影響標(biāo)志位
?
簡(jiǎn)單解釋下減法法命令對(duì)標(biāo)志位的影響
MOV BX, 9048H ; BL=48H ? BH = 90H
SUB BH,BL ?; ?BL(48H) = ?90H ?- 48H? ?1001 0000 - 0100 1000 ?=?0100 1000?
; 顯然結(jié)果也不為0 所以ZF = 0
; 結(jié)果中1的位數(shù)偶數(shù) PF = 1
; 按照無符號(hào)數(shù) ? 整體沒發(fā)生借位所以CF =0
; 0000 - 0100 借位了所以 ?AF =1
; 按照有符號(hào)數(shù) 90H 實(shí)際表示的數(shù)是 - 70H?
; 所以實(shí)際的計(jì)算是 -70H - 48H = -B8H = -184( 1 0100 1000)
; 很明顯溢出了 所以O(shè)F = 1
; 由于溢出了符號(hào)位被覆蓋了所以本來是負(fù)數(shù)的 現(xiàn)在變成正數(shù)了所以SF = 0
3.乘法指令
乘法是這樣的被乘數(shù)總是隱藏在AL 或者AX寄存器中,根據(jù)成數(shù)的長(zhǎng)度選擇不同寄存器
(1)無符號(hào)乘法 MUL
MUL OPD1
所以如果OPD 是字節(jié)那么 ? 就是 AX = AL * OPD,如果OPD是字那么 ? 就是 DX AX = AX * OPD,DX存儲(chǔ)數(shù)據(jù)的高16位,AX存儲(chǔ)數(shù)據(jù)的低16位
如果結(jié)果的高半部分不為0 其實(shí)意思 字節(jié) * 字節(jié) = 字,或者 ?字* 字 = 雙字了 CF =1 ,OF =1
?
(2)有符號(hào)乘法?IMUL
IMUL OPDR
用法和MUL完全一樣
由于有符號(hào)乘法的符號(hào)位始終在高字節(jié)中,所以 ?字節(jié) * 字節(jié) 永遠(yuǎn)等于 字,或者 ?字* 字 永遠(yuǎn)等于 雙字了 ,那么標(biāo)記位的變化是根據(jù)高位中是否置包含符號(hào)位而沒有其他有效數(shù)據(jù)來判斷,僅僅是符號(hào)位則 cf =0 of =0
含有有效數(shù)據(jù)則CF =1 OF =1
舉例:
字?jǐn)?shù)據(jù)相乘結(jié)果是 ? 1000 0000 1010 1010 ?那么高位 1000 0000 僅僅是符號(hào)位有數(shù)據(jù)那么 CF =0 OF =0, 如果結(jié)果是1000 0001 1010 1010那么高位1000 0001 中除了符號(hào)位,還有其他有效數(shù)據(jù)所以
CF =1 ,OF =1
?
4.除法指令
和乘法指令一樣,被除數(shù)總是存儲(chǔ)在AX 或者 DX和 AX寄存器中
(1)無符號(hào)除法指令 DIV
DIV OPDR
如果OPDR 是字節(jié)數(shù)據(jù),那么商存儲(chǔ)在 AL寄存器 余數(shù)存儲(chǔ)在 AH寄存器,如果OPDR 是字?jǐn)?shù)據(jù)那么商存儲(chǔ)在AX寄存器 余數(shù)存儲(chǔ)在DX寄存器
不影響標(biāo)志位,但是如果除數(shù)是0 ,或者AL寄存器,或者AX寄存器無法存儲(chǔ)下 商的時(shí)候會(huì)認(rèn)為是溢出,導(dǎo)致觸發(fā)0號(hào)中斷
?
(2)有符號(hào)觸發(fā)指令 IDIV
IDIV OPDR
存儲(chǔ)結(jié)果的方式和無符號(hào)除法一樣?
也不影響標(biāo)志位,當(dāng)除數(shù)是0,或者寄存器無法保存下結(jié)果的時(shí)候觸發(fā)0號(hào)中斷
?
5.符號(hào)位擴(kuò)展指令
(1)字節(jié)轉(zhuǎn)換為字指令 CBW
CBW
將AL寄存器的數(shù)據(jù)的符號(hào)位放到到AH,功能就是AX =AL
效果就是假設(shè) ?AL= 1001 0001 AH = 0000 0000,CBW后 AL= 0001 0001 AH = 1000 0000?
?
(2)字轉(zhuǎn)雙字 CWD
CWD
將AX的符號(hào)位擴(kuò)展到DX中,作用同CBW一樣
?
邏輯運(yùn)算和移位指令
基本規(guī)則
如果指令有兩個(gè)操作數(shù),則最多只能有一個(gè)是存儲(chǔ)器操作數(shù)
只有通用寄存器和存儲(chǔ)器可以用于存放操作結(jié)果
1.?邏輯運(yùn)算指令
(1)否操作指令 NOT
NOT OPRD
這條指令的作用就是將操作數(shù)OPRD取反,然后存儲(chǔ)到OPRD中去
?
(2)與操作指令 AND
AND OPRD1, OPRD2
將兩個(gè)操作數(shù)進(jìn)行按位的與操作,然后結(jié)果存儲(chǔ)到OPRD1中,注意這個(gè)操作會(huì)影響PF ZF SF 標(biāo)志位,所以有個(gè)技巧就是自己與自己進(jìn)行于運(yùn)算可以清除 進(jìn)位標(biāo)志CF
?
(3)或操作指令 OR
OR OPRD1, OPRD2
將兩個(gè)操作數(shù)進(jìn)行或操作,結(jié)果存儲(chǔ)到OPRD1中,這個(gè)操作也是會(huì)影響會(huì)影響PF ZF SF 標(biāo)志位,并且也可是通過自己或自己的方式清除 進(jìn)位標(biāo)志CF
?
(4)異或操作 XOR
XOR OPRD1, OPRD2
將兩個(gè)操作數(shù)進(jìn)行異或操作,結(jié)果保存到OPRD1中,這個(gè)操作也是會(huì)影響會(huì)影響PF ZF SF 標(biāo)志位,如果自己和自己異或?qū)?huì)得到0 并且也會(huì)清除 進(jìn)位標(biāo)志 CF
?
(5)測(cè)試指令 TEST
TEST OPRD1, OPRD2
這條指令也是進(jìn)行邏輯與操作的,和AND指令的不同在于他不將結(jié)果存儲(chǔ)到OPRD1中,也就是說這個(gè)指令只影響標(biāo)志位,不影響操作數(shù)。
舉例:
比如想測(cè)試AL中的 第6和第2位是否為1 則可以使用指令
test al, 01000100B
如果都為一則ZF標(biāo)志位會(huì)置位,否則ZF=0
?
2.一般移位指令
移位指令分為 左移 和 右移指令,在這基礎(chǔ)上還分為邏輯移動(dòng)和算數(shù)移動(dòng)兩種,所以一共有四條指令
SAL OPRD, m ; 算數(shù)左移
SHL OPRD, m ?;邏輯左移
SAR OPRD, m ?;算數(shù)右移
SHR OPRD, m ? ? ;邏輯右移
其中 m 移動(dòng)的位數(shù), 要么是1 要么是AL寄存器
移位操作會(huì)影響 PF, SF, ZF和 OF標(biāo)志位
對(duì)于左移操作,其實(shí)算數(shù)左移和邏輯左移是一模一樣的, 將操作數(shù)OPRD 向左移動(dòng)m位,每移動(dòng)一位右邊會(huì)補(bǔ)0 ,同時(shí)移動(dòng)出去的最高位會(huì)進(jìn)入CF 標(biāo)志位。
對(duì)于右移操作,算數(shù)右移會(huì)保持左邊的符號(hào)位不動(dòng)其他位右移,而邏輯右移則不考慮符號(hào)位不符號(hào)位的通通右移, 空位用0 補(bǔ)足,最高位進(jìn)入CF標(biāo)志位 。所以算數(shù)右移1位相當(dāng)于 ?有符號(hào)數(shù)/無符號(hào)數(shù) 除以2 ? ?而邏輯右移通通認(rèn)為是無符號(hào)數(shù) 除以2
?
3.?循環(huán)移位指令
循環(huán)移位和一般移位的區(qū)別就是,一般移位就是移動(dòng)多少位之后移出去的直接丟棄,后面補(bǔ)0,而循環(huán)移位會(huì)將移動(dòng)出去的位放到另一端,將向一個(gè)圈不停的轉(zhuǎn),舉個(gè)例子
比如 操作數(shù) ?
一般左移的結(jié)果就是 ? ?01010101 =>?10101010 ?=>?01010100 => 10101000 => 01010000??=> 10100000??=> 01000000
循環(huán)左移的結(jié)果就是 ???01100101 =>??11001010 =>?10010101 =>?00101011 => 01010110 =>?10101100 =>?01011001
循環(huán)移位分為帶進(jìn)位的循環(huán)移位和不帶進(jìn)位的循環(huán)移位
ROL OPRD, m ; ?循環(huán)左移,他每移動(dòng)一位,操作數(shù)左移,最高位進(jìn)入最低位,同時(shí)最高位進(jìn)入CF
ROR OPRD, m ; ?循環(huán)右移,他每移動(dòng)一位,操作數(shù)右移,最低位進(jìn)入最高位,同時(shí)最低位進(jìn)入CF
RCL OPRD, m ; ?帶進(jìn)位的循環(huán)左移,他每移動(dòng)一位,操作數(shù)左移,最高位進(jìn)入CF標(biāo)志,原來的CF進(jìn)入最低位
RCR OPRD, m ; ?帶進(jìn)位的循環(huán)右移,他每移動(dòng)一位,操作數(shù)左移,最低位進(jìn)入CF標(biāo)志,原來的CF進(jìn)入最高位
? 帶進(jìn)位標(biāo)志的循環(huán)移動(dòng)就相當(dāng)于 在原來的操作數(shù)前面多加了一位進(jìn)行移位操作,原來是 8位操作數(shù)那么CF就添加到最前面變成9位操作數(shù)進(jìn)行移位操作。所以 不帶進(jìn)位的循環(huán)移動(dòng)每移動(dòng)8位相當(dāng)于還原,帶進(jìn)位的循環(huán)移動(dòng)每移動(dòng)9位則相當(dāng)于還原。
帶進(jìn)位的循環(huán)的一個(gè)用處就是可以將其他操作數(shù)的最低位或者最高位送入CF,然后將CF循環(huán)入另一個(gè)操作數(shù)來完成數(shù)據(jù)的拼裝。
?
程序控制
? 基本規(guī)則
8086/8080 CPU提供了大量的用于流程控制的指令,按照功能可以分為如下四類
無條件轉(zhuǎn)移指令和有條件轉(zhuǎn)移指令
循環(huán)指令
過程調(diào)用和過程返回指令
軟中斷指令和中斷放回指令
同時(shí)根據(jù)轉(zhuǎn)移的時(shí)候是否設(shè)置CS寄存器的值又分為 段內(nèi)轉(zhuǎn)移(近轉(zhuǎn)移) 和 段間轉(zhuǎn)移(遠(yuǎn)轉(zhuǎn)移)
條件轉(zhuǎn)移和 循環(huán)指令 只能是 段內(nèi)轉(zhuǎn)移
軟中斷指令和中斷放回指令 只能是 ?段間轉(zhuǎn)移
無條件轉(zhuǎn)移和過程調(diào)用以及過程返回指令 則是 段內(nèi) 段間都可以
對(duì)于無條件轉(zhuǎn)移和過程調(diào)用指令而言,根據(jù)確定目的地址的方式不同還分為直接轉(zhuǎn)移和間接轉(zhuǎn)移
無條件,條件,循環(huán)指令是不影響標(biāo)志位的
?
1. 無條件轉(zhuǎn)移指令
(1)無條件段內(nèi)直接轉(zhuǎn)移指令 JMP
JMP 標(biāo)號(hào)
這條指令是的控制無條件地轉(zhuǎn)移到標(biāo)號(hào)地址處。 例如
NEXT: ? ?MOV AX,CX
......
JMP NEXT
對(duì)于這條指令對(duì)應(yīng)的機(jī)器指令是
指令操作碼 | 地址差
地址差會(huì)在編譯的時(shí)候由編譯器計(jì)算出,計(jì)算的是目的地和JMP指令之后下一條指令的差值,所以這條指令的實(shí)際操作就是將差值加到IP寄存器上。
如果地址差需要一個(gè)字節(jié)表示那么稱之為 短轉(zhuǎn)移, 如果需要一個(gè)字表示那么稱之為近轉(zhuǎn)移。使用一個(gè)字還是一個(gè)字節(jié)表示地址差會(huì)在編譯的時(shí)候計(jì)算。編譯器是順序編譯的,如果編譯到這條JMP指令的時(shí)候還沒出現(xiàn)JMP的那個(gè)標(biāo)號(hào)
那么編譯器就無法計(jì)算出地址差,這個(gè)時(shí)候編譯器會(huì)默認(rèn)使用字作為操作數(shù),如果你能確定實(shí)際上字節(jié)就夠了,那么你可以是使用SHORT指令顯式的告訴編譯器使用字節(jié)地址,具體指令格式如下
JMP SHORT NEXT
這個(gè)使用地址差的轉(zhuǎn)移方式,稱之為相對(duì)轉(zhuǎn)移,相對(duì)轉(zhuǎn)移是有利于代碼段的浮動(dòng)加載,意思是無論代碼加載在內(nèi)存哪個(gè)位置都可以很好的運(yùn)行。
?
(2)無條件段內(nèi)間接轉(zhuǎn)移 JMP
JMP OPRD
這條指令控制無條件的轉(zhuǎn)移到OPDR指定的地指出, OPRD可以是通用寄存器也可以是字存儲(chǔ)單元,如下
JMP CX
JMP WORD PTR [1234H]
?
(3)無條件段間直接轉(zhuǎn)移 JMP
JMP FAR PTR 標(biāo)號(hào)
FAR PTR 就是只是編譯器這是一個(gè)斷間轉(zhuǎn)移。
JMP FAR PTR NEXT
生成的機(jī)器指令將會(huì)是
操作碼 ? 偏移地址 ?段地址
這種指令中直接包含轉(zhuǎn)移目的地的轉(zhuǎn)移方式叫做絕對(duì)轉(zhuǎn)移
?
(4)無條件斷間間接轉(zhuǎn)移 JMP
JMP OPRD
OPRD 必須是雙字的所以指令一般如下
JMP DWORD PTR [1234H]
那么內(nèi)存1234H處低字節(jié)存儲(chǔ)的就是IP 高字節(jié)存儲(chǔ)的就是CS
順帶一提PTR 類似于 指針的意思, ? XXX ptr 就指定接下來的數(shù)據(jù) 是 什么類型的指針 ?作用大致相當(dāng)于 C 中的 ?強(qiáng)制類型轉(zhuǎn)換 (XXX*) ? ?比如 ? ? ??DWORD PTR ?A 相當(dāng)于 (DWORD*) A
2. 條件轉(zhuǎn)移指令
條件轉(zhuǎn)移都是段內(nèi)轉(zhuǎn)移,同時(shí)先使用相對(duì)轉(zhuǎn)移,即通過在IP地址上加個(gè)地址差的方式實(shí)現(xiàn)。
條件轉(zhuǎn)移是不影響標(biāo)志位的。
下圖是網(wǎng)上找到的關(guān)于條件轉(zhuǎn)移指令的說明
?
有符號(hào)數(shù) 大于使用G 等于使用E 小于使用L
無符號(hào)數(shù)?大于使用A 等于使用E 小于使用B
N 表示不
?
條件轉(zhuǎn)移指令需要配合CMP指令或者TEST等其他指令來配合使用
先使用CMP等指令進(jìn)行操作,這會(huì)影響到標(biāo)志位,然后使用以上的指令就會(huì)根據(jù) CMP等指令影響的標(biāo)志位做出反映。
?
?循環(huán)指令
使用條件轉(zhuǎn)移指令可以實(shí)現(xiàn)循環(huán),但是為了方便操作8086CPU還是設(shè)計(jì)了四個(gè)循環(huán)指令
? (1)計(jì)數(shù)循環(huán)指令 LOOP
LOOP 標(biāo)號(hào)
這條指令使寄存器CX的值減1,如果結(jié)果不等于0,則轉(zhuǎn)移到標(biāo)號(hào),否則順序執(zhí)行LOOP指令后的指令。
所以LOOP 相當(dāng)于
DEC CX
JNZ 標(biāo)號(hào)
?
(2)等于/全零循環(huán)指令 LOOPE/LOOPZ
LOOPE 標(biāo)號(hào)
或者
LOOPZ 標(biāo)號(hào)
這條指令使寄存器CX的值減1,如果結(jié)果不等于0,并且ZF=1, 則轉(zhuǎn)移到標(biāo)號(hào),否則順序執(zhí)行LOOP指令后的指令。這條指令的CX減一操作不影響標(biāo)志位。
(3)不等于/非全零循環(huán)指令 LOOPNE/LOOPNZ
LOOPNE 標(biāo)號(hào)
或者
LOOPNZ 標(biāo)號(hào)
這條指令使寄存器CX的值減1,如果結(jié)果不等于0,并且ZF=0, 則轉(zhuǎn)移到標(biāo)號(hào),否則順序執(zhí)行LOOP指令后的指令。這條指令的CX減一操作不影響標(biāo)志位。
?
(4)跳轉(zhuǎn)指令 JCXZ
JCXZ 標(biāo)號(hào)
該指令執(zhí)行當(dāng)CX=0的時(shí)候轉(zhuǎn)跳到標(biāo)號(hào)處,否則順序執(zhí)行
?
?標(biāo)志操作指令
此組命令是專門針對(duì)標(biāo)記寄存器和標(biāo)志位進(jìn)行的。
1. 標(biāo)志傳送指令
(1) LAHF指令(Load AH with Flags)
LAHF
此指令是將標(biāo)志位的低8位(SF ZF AF PF CF)保存到AH 寄存器中
?
(2) SAHF指令(Store AH with Flags)
SAFH
此指令和LAHF是相對(duì)的,SAFH指令是將AH寄存器中的內(nèi)容傳送到標(biāo)記寄存器的低八位
?
(3) PUSHF 指令
PUSHF
此指令是將標(biāo)志寄存器的內(nèi)容全部壓棧。
?
(4) POPF 指令
POPF
此命令和PUSHF是一對(duì)的,將堆棧中的數(shù)據(jù)傳送到標(biāo)記寄存器。
?
2. 標(biāo)志位操作指令
此組指令是專門用來處理指定標(biāo)志位的。
(1) 清進(jìn)位標(biāo)志位 CLC (Clear Carry flag)
CLC
使進(jìn)位標(biāo)志設(shè)為0
?
(2) 置進(jìn)位標(biāo)志位 STC (SeT Carry flag)
STC
使進(jìn)位標(biāo)志設(shè)為1
?
(3) 進(jìn)位標(biāo)志取反 CMC (CoMplement Carry flag)
CMC
如果CF=1 則 CF 置為0 ,如果CF=0 則 CF置為1
?
(4) 清方向標(biāo)志 CLD (CLear Direction flag)
CLD
使方向標(biāo)志DF 置為0,使串操作地址按照增的方式變化
?
(5) 置方向標(biāo)志 STD (Set Direction flag)
STD
使方向標(biāo)志DF 置為0, 使串操作地址按照減的方式變化
(6) 清中斷允許標(biāo)志 CLI (CLear Interrupt enable flag)
CLI
該指令使中斷允許標(biāo)志IF 設(shè)為0 ,于是CPU就不響應(yīng)外部裝置的可屏蔽中斷,但是對(duì)不可屏蔽中斷和內(nèi)部中斷都沒有音響。
?
(7) 置中斷允許標(biāo)志 STI (SeT Interrupt enable flag)
STI
該指令使中斷允許標(biāo)志IF 設(shè)為1 ,這樣CPU就可以相應(yīng)可屏蔽中斷
轉(zhuǎn)載于:https://www.cnblogs.com/alwaysking/p/6659343.html
總結(jié)
以上是生活随笔為你收集整理的汇编学习笔记(3)-80x86指令集的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一部手机可以下载多个微信app吗?
- 下一篇: [NOIP2014]飞扬的小鸟