OD汇编指令 | |
NOP | 无操作 |
PUSH | 将数据压如堆栈中 |
POP | 出栈(与PUSH相反) |
PUSHAD | 所有通用寄存器的内容按一定顺序压入到堆栈中,相当于’PUSH EAX,PUSH ECX,PUSH EDX,PUSH EBX,PUSH ESP,PUSH EBP,PUSH ESI, PUSH EDI’ |
POPAD | 该指令与PUSHAD正好相反,它从堆栈中取值,并将它们放到相应的寄存器中,等价于“POP EDI,POP ESI,POP ESP,POP ESP,POP EBX,POP EDX,POP ECX,POP EAX” |
MOV | 该指令将第二个操作数赋值给第一个操作数 |
MOVSX (带符号扩展的传送指令) | 第二个操作数可能是一个寄存器也可能是一个内存单元,第一个操作数的位数比第二个操作数多,第二个操作数的符号位填充第一个操作数剩余部分 |
MOVZX (带0扩展的传送指令) | 类似于MOVSX,但是这种情况下剩余的部分不根据操作数的正负来进行填充,剩余的部分总是被填充为0 |
LEA (取地址指令) | 类似于MOV指令, 但是第一个操作数是一个通用寄存器,并且第二个操作数是一个内存单元。当计算的时候要依赖于之前的结果的话,那么这个指令就非常有用 |
XCHG | 交换 寄存器/内存单元 和 寄存器 |
OD数学指令 | |
INC | 执行增加,如果是INC指令的话,就加1 |
DEC | 执行减少,如果是DEC指令的话,就减1 |
ADD | ADD指令有两个操作数,相加后的结果存放到第一个操作数中,ADD EAX,1等价于INC EAX |
ADC (带进位的加法) | 两个操作数的和加上进位标志的值,结果存放到第一个操作数中 |
SUB | 这个指令与ADD刚好相反,它将第一个操作数减去第二个操作数的值存放到第一个操作数中 |
SBB | 该指令跟ADC正好相反,它计算两个操作数的差值,并且还要减去进位标志,结果存放到第一个操作数中 |
MUL (无符号数的乘法) | 有两种乘法: |
IMUL (有符号数的乘法) | IMUL指令用法类似于MUL,例如:IMUL ECX 该指令将有有符号数ECX乘以EAX,结果存放到EDX:EAX中 |
DIV && IDIV | 无符号除法/有符号除法;这两个指令反别与MUL和IMUL相反 |
XADD (交换并相加) | 这个指令其实就是XCHG和ADD两个简单指令的组合 |
NEG | 该指令的目的是将操作数的符号取反,即如果我们有一个32位的16进制数,用NEG操作以后,结果就会取反 |
逻辑指令 | 逻辑指令有两个操作数,两操作数按位运算,并将结果存放到第一个操作数中 |
AND | 只有两个二进制位都为1的时候结果才为1,其他情况,结果都为0;例: |
OR | 该指令与AND的不同之处在于,两位中只要有一位为1,结果就取1; |
XOR | 该指令运算,当两位不同时取1,相同时取0 |
NOT | 该指令是简单的按位取反 |
比较和条件跳转 | |
CMP | CMP EAX, ECX |
TEST (逻辑比较) | TEST EAX,EAX |
JUMPS | 所有的跳转指令都会指向程序将会跳转到的地址。 |
JMP | 这是一个无条件跳转指令,即总是跳转到指定的地址 |
JE或者JZ | 若相等则跳;如果零标志位Z不为0则跳转,即,要求操作的结果为零 |
JNE或JNZ | 若不等则跳转;如果零标志位Z为0则跳转,即,要求操作的结果非零 |
JS | JS EAX,ECX |
JNS | JNS EAX,ECX |
JP或JPE | 这个跳转指令是当奇偶标志位P置1的时候才会发生,也就是比较的结果中1的个数要是偶数才会跳转 |
JNP 或JNPE | 这条指令刚好与上一条指令刚好相反,当奇偶标志位P为0的时候跳转。即结果中1的个数为奇数的时候 |
JO | 当发生溢出时,即溢出标志位O置1的时候跳转 |
JNO | 跟上一条指令相反,这里是当溢出标志位O为0时跳转,即溢出没有发生时 |
JB | 第一个操作数小于第二个操作数的时候跳转 |
JNB | 和JB指令相反,这个指令是当进位/借位标志位为0的时候跳转,也就是说,结果为正的时候跳转也就是说第二个第一个操作数大于第二个操作数的时候跳转 |
JBE | JBE EXA,ECX |
JNBE | 这个指令跟JBE刚好相反,当进位/借位标志位C与零标志位Z都为0时候才会发生跳转, |
JL | 这个指令当小于的时候跳转,但是与前面的JB稍微有点不同。这个指令时根据符号标志位S来决定是否跳转 |
CALL | 是指将转移到指定的子程序处,它的操作数就是给定的地址;例: |
RET(RETN) | 返回到指定位置,当我们执行到ret指令的时候,栈顶存放的一般是子程序的返回地址;也就是说ret指令是子程序的结束,也就是说,如果我们call跟进的话,那么ret就能返回到call指令的下一条语句处。当然RET指令不止适用于子程序返回,例如: |
循环指令 | 为了实现循环可以使用前面介绍过一些指令。例如,你可以将任意通用寄存器指定为计数器(通常ECX作为计数器使用),你可以将其初始化为需要循环的次数,然后执行循环体,接着计数器递减1,判断计数器是否为0,如果计数器不为0继续重复前面的过程,如果计数器为0,就不继续循环了,而直接执行下面的代码。代码如下: |
LOOP | LOOP指令可以帮我们完成前面例子中的事情- 将计数器ECX的值减1,判断ECX的值是否为0,如果为0就跳转到指定的地址-将像前面的例子一样。(可惜的是,大多数现代的处理器中该指令的效率不如前面模拟的例子。) |
LOOPZ LOOPE | 重复循环,直到零标志位Z置1 |
LOOPNZ LOOPNE | 重复循环,直到零标志位Z清0 |
比较全面的OD指令
最新推荐文章于 2023-12-20 08:51:05 发布