您的位置:首页 > 其它

汇编-条件跳转与重复指令

2015-04-30 12:16 309 查看

条件跳转

速记方法:

j(jmp)

z(zero)

n(not)

e(equal)

g(greater)

l(less)

a(above,无符号)

b(below,无符号)

汇编指令x86下  指令+目的操作数+原操作数 比较是用目的操作数去和原操作数比较

jz loc   当cmp的两个值相等的时候跳转,否则继续执行下一条
jnz loc  当cmp的两个值不相等的时候跳转,否则继续执行下一条

je loc   当cmp的两个值相等的时候跳转,否则继续执行下一条
jne loc  当cmp的两个值不相等的时候跳转,否则继续执行下一条

jg loc  (cmp eax,ebx)当eax大于ebx时执行跳转,否则继续执行下一条
jge loc (cmp eax,ebx)当eax大于或等于(不小于)ebx时执行跳转,否则继续执行下一条

ja loc  ja=jg 不过是无符号数比较
jae loc jae = jge 不过是无符号数比较

jl loc  (cmp eax,ebx)当eax小于ebx时执行跳转,否则继续执行下一条
jle loc (cmp eax,ebx)当目的操作数小于或等于原操作数时,跳转,否则执行下一条

jb loc 和 jl 一样,不过是无符号的比较
jbe loc 和jle一样,不过是无符号数的比较

后面两个不怎么常用,但是记录一下吧:
jo loc 如果上一条指令执行后(of=1),则跳转(溢出跳转)
js loc 如果符号位被置位(sf=1),则跳转

jecxz loc (jmp if ecx = 0)


重复指令

这里说的重复指令是对字符串数组的操作。字符串数组操作的最小原子步骤一般为:

movsx,cmpsx,stosx,scasx
,x则可以是
b(byte),w(word),d(dword)
,这一部分会在后面细讲。

使用这些操作时,用
esi(source addr)
充当源地址,
edi(destination addr)
充当目的地址。

因为字符串的比较和移动,需要对长度作以限制,所以需要一个长度参数,一般用
ecx
来计数。

重复指令用
rep
来表示,终止条件为:

rep 当ecx不为0的时候重复后面指令

repe,repz 当ecx不为0,并且 zf=1的时候重复后面指令

repne ,repnz 当ecx不为0,并且 zf=0的时候重复后面指令

REP/REPE/REPNE

The string instructions may be prefixed by REP/REPE/REPNE which will repeat the

instructions according to the following conditions:

rep       decrement cx ; repeat if cx is not zero
repe      decrement cx ; repeat if cx not zero AND zf = 1
repz      decrement cx ; repeat if cx not zero AND zf = 1
repne     decrement cx ; repeat if cx not zero AND zf = 0
repnz     decrement cx ; repeat if cx not zero AND zf = 0


Here, ‘e’ stands for equal, ‘z’ is zero and ‘n’ is not. These repeat instructions

should NEVER be used with a segment override, since the 8086 will forget the

override if a hardware interrupt occurs in the middle of the REP loop.

在x86下,使用重复前缀来做多字节操作,
rep
会增加
esi 和edi
这两个偏移,并且同时减少
ecx
的值,rep前缀会不断重复,直到终止条件到来。因此,需要在使用前初始化
esi,edi,ecx


movsb 从
esi
指向的地址中获取一个字节,并存放到
edi
中(需要用df方向标志来确定移动方向,esi+1,edi+1或esi-1,edi-1)

cmpsb 用于esi和edi字符串的比较(单字节比较),更新ZF标志位。(
memcmp


scasb
用于从esi
edi
指向的字符串中比较第一个值,这个值由
al
指出,所以需要初始化
al
。注意,不是用
esi
edi
比较,寻找到的位置会存放到
edi
中。执行完毕之后,edi会+1.

stosb 用于将值存放到
edi
指向的地址。(
memset


rep指令的常用组合

repe cmpsb 比较
esi
edi
指向的字符串,当字符串不同或者ecx=0的时候停止

rep stosb (repeat store string by byte)用于用一个给定的值初始化缓冲区中所有字节。
edi
包含了缓冲区地址,
al
则包含了初始值。

rep movsb 将
esi
指向的字符串复制到
edi
中,长度为
ecx
。(单字节复制,rep加偏移1(update;不是rep加了偏移,而是movsb指令使edi esi加1),ecx表示重复次数)

repne scasb 从
edi
中搜索单字节(
al
),并将结果放在
esi
中,
ecx
为缓冲区长度。

比较movsb和stosb

movsb需要指定两个字符串,
esi and edi
.

stosb只需要指定
edi
,要复制的是单个字节,由
al
给定。

jz=je

jne 解读:
jne = jnz            = if(prev  nz) j
so:
jne 403000: <=>
if (nz)  j 403000 <=>
if( 指令上方表达式  !=0)  go 403000

比如 test eax,eax
jne 403000

if(test eax,eax   !=0) goto 403000
即
if(eax|eax !=0)  goto 403000

但是 mov eax,0  不会使得ZF=1.因为mov指令不影响此值。


参考资料:

恶意代码分析实战P74-76

指令集查询
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  汇编 指令