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

条件跳转

速记方法:

  • 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 用于从字符串中搜索一个值,这个值由al指出,所以需要初始化al。注意,不是用esiedi比较,寻找到的位置会存放到esi中。
  • stosb 用于将值存放到 edi指向的地址。(memset

rep指令的常用组合

  • repe cmpsb 比较esiedi指向的字符串,当字符串不同或者ecx=0的时候停止
  • rep stosb (repeat store string by byte)用于用一个给定的值初始化缓冲区中所有字节。edi包含了缓冲区地址,al则包含了初始值。
  • rep movsb 将esi指向的字符串复制到edi中,长度为ecx。(单字节复制,rep加偏移1,ecx表示重复次数)
  • repne scasb 从edi中搜索单字节(al),并将结果放在esi中,ecx为缓冲区长度。

比较movsb和stosb

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

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

参考资料:

恶意代码分析实战P74-76

指令集查询

时间: 2024-11-06 07:48:03

汇编-条件跳转与重复指令的相关文章

x86汇编 条件跳转

条件跳转表 汇编语言-条件跳转指令 直接转移指令 指令格式 机器码 测试标志 条件说明 符号  JO       OPR 70  OF=1  结果有溢出    JNO      OPR 71  OF=0  结果无溢出    JC       OPR 72  CF=1  小于  <  JNC      OPR 73  CF=0  大于或等于  >=  JZ/JE    OPR 74  ZF=1  结果为0  ==  JNZ/JNE  OPR 75  ZF=0  结果非0  !=  JS     

linux平台学x86汇编(八):条件跳转

[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途] 在此之前我们使用的汇编代码示例都是从第一条指令开始,直到最后最后一条指令程序退出.但实际上和高级语言类似,汇编代码也提供指令来改变程序处理数据方式. 正常情况下,程序要执行要执行的下一条指令是在指令指针寄存器中,指令指针确定程序中哪条指令是应该执行的下一条指令. 当指令指针在程序指令中移动时,EIP寄存器会递增.指令长度可能是多个字节,所以指向下一条指令不仅仅是每次是指令指针

汇编语言--条件跳转指令

修改自: http://bdxnote.blog.163.com/blog/static/84442352015327011988/ 在此向原作者致敬, 网上大多数帖子都是拷贝自一个把跳转条件写错了的帖子, 害的我差点要怀疑人生了,-_-! . 本贴主要是把原作者的跳转条件改成C语言逻辑表达式的写法, 这样看着更舒服一些, 而且不会产生歧义 直接转移指令 指令格式 机器码 跳转条件 条件说明 符号  JO       OPR 70  OF==1  结果有溢出    JNO      OPR 71

linux平台学x86汇编(九):循环指令

[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途] 循环也是改变指令执行顺序的一种方式,循环操作重复的执行,直到满足条件.我们可以使用条件跳转指令来创建循环,但事实上汇编语言中有更简单的循环指令系列. 循环指令使用ECX寄存器作为计数器,随着循环指令的执行自动递减它的值,并且不会影响EFLAGS寄存器的标志位,当ecx寄存器值到达0时,0标志不会被设置.循环指令有如下:loop(循环直到ecx寄存器为0).loope/loop

标志寄存器PSW和汇编条件转移指令解释

标志寄存器PSW 标志寄存器PSW(程序状态字寄存器PSW)   标志寄存器PSW是一个16为的寄存器.它反映了CPU运算的状态特征并且存放某些控制标志.8086使用了16位中的9位,包括6个状态标志位和3个控制标志位. CF(进位标志位):当执行一个加法(减法)运算时,最高位产生进位(或借位)时,CF为1,否则为0.ZF零标志位:若当前的运算结果为零,则ZF为1,否则为0.SF符号标志位:该标志位与运算结果的最高位相同.即运算结果为负,则SF为1,否则为0.OF溢出标志位:若运算结果超出机器能

Java逆向基础之条件跳转位运算循环

本文参考:http://www.vuln.cn/7117 条件跳转的例子,绝对值 public class abs {     public static int abs(int a)     {         if (a<0)             return -a;         return a;     } } 编译 javac abs.java 反编译 javap -c -verbose abs.class   public static int abs(int);     d

基于8086CPU微处理器的汇编学习之PUSH、POP指令

--------------------------------------------- 栈,是一种数据结构,我觉得栈是抽象的,但是它同样也是实际的,因为它在内存中是连续的内存,只不过人们限制了它的使用:后进先出,学数据结构两年了,现在才理解,实在惭愧. push  ax   ;I.sp = sp - 2                  II .取出ax中的数据,放入当前栈顶 pop   ax   ;I.栈顶地址取出数据,放入ax中   II.sp = sp + 2 ------------

2018/10/03-字符串指令(重复指令、操作数据缓冲区指令)、rep与movx指令-《恶意代码分析实战》

重复指令是一组操作数据缓冲区的指令.数据缓冲区通常是一个字节数组的形式,也可以是单字或者双字.(Intel'称这些指令为字符串指令) 最常见的数据缓冲区操作指令是movsx.cmps.stosx和scasx,其中x可以是b.w后者d,分别表示字节.字和双字.这些指令对任何形式的数据都有效. 在这些操作中,使用ESI和EDI寄存器.ESI是源索引寄存器,EDI是目的索引寄存器.还有ECX用作计数的变量. 这些指令还需要一个前缀,用于对长度超过1的数据做操作.movsb指令本身只会移动一个字节,而不

汇编常用跳转指令及检测的标志位

  助记符 条件( 执行 CMP A,B 之后的标志位) 表达式 无符号数 JB/JNAE CF=1 A < B JAE/JNB CF=0 A ≥ B JA/JNBE CF=0 and ZF=0 A > B JBE/JNA CF=1 or ZF=1 A ≤ B 有符号数 JL/JNGE SF ≠ OF A < B JGE/JNL SF=OF A ≥ B JG/JNLE SF=OF and ZF=0 A > B JLE/JNG SF ≠ OF or ZF=1 A ≤ B 无符号数或有