asm基础——汇编指令之比较测试指令

来源:互联网 发布:上海小众景点 知乎 编辑:程序博客网 时间:2024/05/29 03:20

汇编中的某些指令改变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.datasrc  DB 12h, 34h, 56h,  78hdest DB 12h, 34h, 0FFh, 0FFh.codemain PROCcld                     ; 清除方向标识,这样cmpsb操作时,esi和edi会递增mov ecx, LENGTHOF src   ; 用来获取循环次数,这里的ecx的值变成4mov esi, OFFSET src     ; 设置源数据地址mov edi, OFFSET dest    ; 设置目标数据地址call DumpRegs           ; 打印寄存器,与下一次进行比较,比较项主要是edi、esi和ecxrepe cmpsb              ; repe表示相等时继续循环                                ; cmpsb是比较字节call DumpRegs           ; 打印寄存器,exitmain ENDPEND main
得到的结果如下:


CMPXCHG

比较并交换。

OF

DF

IF

SF

ZF

AF

PF

CF

*

 

 

*

*

*

*

*

说明:目的操作数和累加器(AL/AX/EAX)比较,如果相等,则源操作数复制到目的操作数,否则目的操作数复制到累加器。

指令格式:

cmpxchg reg, reg    

cmpxchg mem, reg

下面是一个例子:

INCLUDE Irvine32.inc.datasrc  DB 12h, 34h, 56h,  78hdest DB 12h, 34h, 0FFh, 0FFh.codemain PROCmov esi, OFFSET src      ; 设置源数据地址mov edi, OFFSET dest     ; 设置目标数据地址mov eax, 0FFh            ; eax=FFhcmpxchg [esi], eax       ; 因为[esi]的值与eax中的值不相等,所以[esi]的值就复制到了eax中call DumpRegs            ; 打印寄存器,eax的值应该是78563412hexitmain ENDPEND 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.datasrc  DB 12h, 34h, 56h,  78hdest DB 12h, 34h, 0FFh, 0FFh.codemain PROCxor eax,eax       ; eax = 0stc               ; cf = 1call DumpRegsbtc eax, 1        ; 将eax中的bit2取反,所以eax = 0x2, cf = 0call DumpRegsexitmain ENDPEND 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.codemain PROCxor eax, eaxor eax, 1        ; eax的bit0被置位test eax, 1      ; 判断eax的bit0是否被置位                         ; 从这里可以看到是置位了,所以ZF = 0call DumpRegstest eax, 2      ; 判断eax的bit1是否被置位                         ; 从这里可以看到是置位了,所以ZF = 1call DumpRegsexitmain ENDPEND main
得到的结果:



0 0
原创粉丝点击