1. 程式人生 > >asm基礎——彙編指令之比較測試指令

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
得到的結果: