asm基礎——彙編指令之比較測試指令
彙編中的某些指令改變CPU標識位的值,這些命令中,有些指令改變標識位只是其附帶效果,比如add指令的和溢位時就會改變CF標識;而另外一些標識,它們的主要作用就是改變標誌位,從而控制彙編程式的流程。
以下是幾個常用的指令:
CMP
比較。
OF |
DF |
IF |
SF |
ZF |
AF |
PF |
CF |
* |
* |
* |
* |
* |
* |
說明:比較源運算元和目的運算元,“隱含”執行從源運算元中減掉目的運算元的減法操作。這裡“隱含”的意思是相應:設定標誌位,但不改變運算元!它與SUB的不同在於,CMP不修改目的運算元。
指令格式:
cmp reg, reg
cmp reg, imm
cmp mem, reg
cmp mem, imm
cmp reg, mem
cmp accum, imm
與比較相關的還有幾個指令,分別是cmpsb,cmpsw,cmpsd和cmpxchg。
前面三個是同一個型別的,統稱為CMPx,它與REP連用,可以用來比較字串。
CMPx
比較字串。
OF |
DF |
IF |
SF |
ZF |
AF |
PF |
CF |
* |
* |
* |
* |
* |
* |
說明:比較記憶體中有DS:(E)SI和ES:(E)DI定址的字串。隱含執行源運算元減去目的運算元的減法操作。(E)SI和(E)DI的值依據運算元的大小和方向標誌的狀態增減。
指令格式:
cmpsb
cmpsw
cmpsd
下面是一個例子:
得到的結果如下:INCLUDE Irvine32.inc .data src DB 12h, 34h, 56h, 78h dest DB 12h, 34h, 0FFh, 0FFh .code main PROC cld ; 清除方向標識,這樣cmpsb操作時,esi和edi會遞增 mov ecx, LENGTHOF src ; 用來獲取迴圈次數,這裡的ecx的值變成4 mov esi, OFFSET src ; 設定源資料地址 mov edi, OFFSET dest ; 設定目標資料地址 call DumpRegs ; 列印暫存器,與下一次進行比較,比較項主要是edi、esi和ecx repe cmpsb ; repe表示相等時繼續迴圈 ; cmpsb是比較位元組 call DumpRegs ; 列印暫存器, exit main ENDP END main
CMPXCHG
比較並交換。
OF |
DF |
IF |
SF |
ZF |
AF |
PF |
CF |
* |
* |
* |
* |
* |
* |
說明:目的運算元和累加器(AL/AX/EAX)比較,如果相等,則源運算元複製到目的運算元,否則目的運算元複製到累加器。
指令格式:
cmpxchg reg, reg
cmpxchg mem, reg
下面是一個例子:INCLUDE Irvine32.inc
.data
src DB 12h, 34h, 56h, 78h
dest DB 12h, 34h, 0FFh, 0FFh
.code
main PROC
mov esi, OFFSET src ; 設定源資料地址
mov edi, OFFSET dest ; 設定目標資料地址
mov eax, 0FFh ; eax=FFh
cmpxchg [esi], eax ; 因為[esi]的值與eax中的值不相等,所以[esi]的值就複製到了eax中
call DumpRegs ; 列印暫存器,eax的值應該是78563412h
exit
main ENDP
END main
得到的結果如下:
其它的比較測試指令還有如下的:
BT/BTC/BTR/BTS
位測試
OF |
DF |
IF |
SF |
ZF |
AF |
PF |
CF |
? |
? |
? |
? |
? |
* |
說明:將指定位n複製到進位標誌中,目的運算元包含要操作的位號n。BT將源運算元的位n複製到進位標誌中;BTC將源運算元的位n複製到進位標誌中並將位n變反;BTR將源運算元的位n複製到進位標誌中並將位n清除;BTS將源運算元的位n複製到進位標誌中並將位n置1。
指令格式:
BTx r/m16, imm8
BTx r/m16, r16
BTx r/m32, imm8
BTx r/m32, r32
BTx中的x表示C/R/S或者空。注意,這裡BTC中的C表示的是取反,而BTR中的R表示的是清除,這個跟一般想象中的C=Clear,R=Reverse不一樣。下面是一個例子:
INCLUDE Irvine32.inc
.data
src DB 12h, 34h, 56h, 78h
dest DB 12h, 34h, 0FFh, 0FFh
.code
main PROC
xor eax,eax ; eax = 0
stc ; cf = 1
call DumpRegs
btc eax, 1 ; 將eax中的bit2取反,所以eax = 0x2, cf = 0
call DumpRegs
exit
main ENDP
END main
得到的結果如下:
TEST
測試。
OF |
DF |
IF |
SF |
ZF |
AF |
PF |
CF |
0 |
* |
* |
? |
* |
0 |
說明:在每對運算元的對應資料位之間執行隱含的“與”操作,並設定相應的標誌位。它與AND的不同在於,TEST不修改目的運算元。
指令格式:
test reg, reg
test reg, imm
test mem, reg
test mem, imm
test reg, mem
test accum, imm
使用test可以用來判斷某個位是否被置位。下面是一個例子:INCLUDE Irvine32.inc
.code
main PROC
xor eax, eax
or eax, 1 ; eax的bit0被置位
test eax, 1 ; 判斷eax的bit0是否被置位
; 從這裡可以看到是置位了,所以ZF = 0
call DumpRegs
test eax, 2 ; 判斷eax的bit1是否被置位
; 從這裡可以看到是置位了,所以ZF = 1
call DumpRegs
exit
main ENDP
END main
得到的結果: