常用汇编指令

NOP
表示 No Operation ,机器码为 0x90 ,没有操作数,执行这条指令时 CPU 什么事都不干。
PUSH
PUSH 指令将数据压入 中。
指令格式为 push x
x 可取 imm8 imm16 imm32 r/m16 r/m32 r/m64
栈指针寄存器 ESP(RSP) 自动递减。 POP
POP 指令从栈中弹数据。
指令格式为 pop x
x 可取 r/m16, r/m32, r/m64
栈指针寄存器 ESP(RSP) 自动递增。
MOV
MOV 指令将数据从源操作数移动到目的操作数。
指令格式为 mov x1, x2 。意为从 x2 移动数据到 x1
x1, x2 可以是:
寄存器到寄存器
内存到寄存器,寄存器到内存
立即数到寄存器,立即数到内存
不能从内存直接到内存。
LEA
LEA 指令用于载入有效地址。
指令格式为 lea x1, x2
x1 可以是 r16/32/64 x2 是内存地址,常用 [] 语法形式,意为引用求值。
常用于指针运算,有时用于数值计算。
ADD
ADD 指令计算加法操作。
指令格式为 add x1, x2
x1 x2 可以是 r/m16 r/m32 r/m64 x2 还可以是立即数,但二者不能同时是内存操作数。
指令的计算结果将影响 eflflags 寄存器,修改 OF, SF, ZF, AF, PF, CF 标志位。
SUB
SUB 指令计算减法操作。
指令格式为 sub x1, x2
x1 x2 可以是 r/m16 r/m32 r/m64 x2 还可以是立即数,但二者不能同时是内存操作数。
指令的计算结果将影响 eflflags 寄存器,修改 OF, SF, ZF, AF, PF, CF 标志位。
IML/MUL
IMUL 指令用于实现有符号数的乘法运算。
三种指令格式:
imul r/m32 ; edx:eax = eax * r/m32 imul reg, r/m32 ; reg = reg * r/m32
imul reg, r/m32, imm ; reg = r/m32 * imm
MUL 指令是无符号乘法。
IDIV/DIV
DIV 指令用于实现无符号数的除法运算。
两种指令格式:
无符号除法, div ax, r/m8 ; ax 除以 r/m8 al 是商, ah 是余数
无符号除法, div eax, r/m32 ; edx:eax 除以 r/m32 eax 是商, edx 是余数
若被除数是 DWORD ,在指令执行前 edx 被置为 0
若除数是 0 ,则抛出 除零异常
AND
AND 指令实现操作数的逻辑与运算。
指令格式为 and x1, x2
x1, x2 可以是 r/m16, r/m32, r/m64, x2 还可以是立即数,但二者不能同时是内存操作数。
OR
OR 指令实现操作数的逻辑或运算。
指令格式为 or x1, x2
x1, x2 可以是 r/m16, r/m32, r/m64, x2 还可以是立即数,但二者不能同时是内存操作数。
XOR
XOR 指令实现操作数的异或运算。
指令格式为 xor x1, x2
x1, x2 可以是 r/m16, r/m32, r/m64, x2 还可以是立即数,但二者不能同时是内存操作数。
注: XOR 常用于清零运算,如 xor eax, eax ,效率高。
NOT
NOT 指令实现操作数的逻辑非运算。
指令格式为 not x
x 可以取 r/m16, r/m32, r/m64
SHL
SHL 指令用于实现操作数的逻辑左移运算。
指令格式为 shl x1, x2
x1 可以取 r/m16, r/m32, r/m64
x2 可以是 cl 或者占用 1 字节的立即数,表示左移长度 注:左移运算是乘 2 的高效实现方法,被用于乘法性能优化。
SHR
SHR 指令用于实现操作数的逻辑右移运算。
指令格式为 shr x1, x2
x1 可以取 r/m16, r/m32, r/m64
x2 可以是 cl 或者占用 1 字节的立即数,表示右移长度
注:右移运算是除以 2 的高效实现方法,被用于除法性能优化。
JMP
JMP 指令改变 EIP(RIP) 的值到目标地址,实现控制流跳转。
指令格式为 jmp x
x 可取 imm, r/m16, r/m32, r/m64 等。
jmp 目标地址 x 的主要形式:
短跳方式,使用相对地址
近跳方式,使用相对地址
远跳方式(段间转移)
绝对地址,使用直接地址
绝对地址,使用间接地址
Jcc
Jcc 指令是一系列指令的集合,该指令在指定条件满足时将控制流转向目标地址。
指令格式为 jcc x
启动设置:
比较操作设置 eflflags 寄存器的标志位
JNZ 指令,当 eflflags ZF 未被设置( ZF=0 )时,指令满足跳转条件,执行控制转移到目标地址 x
几个常见 jcc 指令的判断条件:
1. 相对于 jmp 指令的下一条指令, 1 字节( -128 ~ 127 )范围
例如, 0x00401021 处指令 “jmp 0x00401028” 为短跳方式,实际上,内存中并没有 0x00401023
一字符串或常量,而是前跳 5 个字节
2. 某些反汇编器将其标记为 jmp short
相对于 jmp 指令的下一条指令,相对地址 4 字节范围
指令中硬编码方式的内存地址
指令中寄存器或内存间接访问的地址 jz/je if ZF == 1
jnz/jne: if ZF == 0
jle/jng: if ZF == 1 or SF != OF
jge/jnl: if SF == OF
jbe: if CF == 1 or ZF == 1
jb: if CF == 1
这些条件通过查看 eflflags 寄存器的相应位进行判断。常用的设置 eflflags 标志位的指令有 cmp, test
运算指令等。
CMP
CMP 指令用于两个操作数的大小比较。
指令格式为 cmp x1, x2
cmp 指令通过将 x1 减去 x2 的方式实现比较,根据减法结果设置 eflflags 的相应标志位,且将减法结果
丢弃。
cmp <-> sub
以相同的方式进行减法操作,以同样的方式设置 eflflags 寄存器
sub 指令将计算结果存入 x1 ,而 cmp 指令不保存计算结果
修改的 eflflags 寄存器标志位有 CF, OF, SF, ZF, AF, PF
TEST
TEST 指令用于两个操作数的逻辑比较。
指令格式为 test x1, x2
test 指令通过计算两个操作数的 逻辑与 ** (&)** 位运算实现比较操作,根据与操作的结果设置 eflflags
相应标志位,且将与操作计算结果丢弃
修改的 eflflags 寄存器标志位有 SF, ZF, PF
CALL
CALL 指令将程序控制流转向一个子函数。
指令格式为 call x ,x 可取 r/m16, r/m32, r/m64, ptr16:16, ptr16:32
启动设置:参数传递,使用 函数调用约定
具体过程:
1. 首先,将下一条指令的地址压入栈中
2. 然后,改变 EIP(RIP) 的值为 x
3. x 可以是绝对地址,也可以是相对于 CALL 指令尾的相对地址 LEAVE
LEAVE 指令用于子函数退出时清理栈的操作,常与 RET 指令配套使用。
实际操作为:
设置 ESP(RSP) EBP(RBP)
弹出栈顶数据到 EBP(RBP)
RET
RET 指令将程序控制流从子函数返回到调用函数。
两种指令格式:
ret
ret x
  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值