【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

得到的结果:

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值