环境
visual studio 选择x86运行
示例代码
/**
| 32位 | 16位 | 高8位 | 低8位 |
| ---- | ---- | ----- | ----- |
| EAX | AX | AH | AL |
*/
#include <iostream>
int main() {
int32_t x = 1;
int32_t y = 2;
// 简单加法示例
__asm {
mov eax, x;
mov ebx, y;
add eax, ebx;
mov x, eax;
};
::std::printf("x = %d y = %d\n", x, y);
return 0;
}
汇编基础
标志位
# visual studio 中的标志位
# OV UP EI PL ZR AC PE CY
- OV 溢出
- 超出表示范围为溢出 1,否则 0
- UP 增量
- 1:以递减顺序对数据串处理;0:以递增顺序对数据串处理
- EI 允许中断
- CPU允许中断1,否则0
- PL 正
- 运算结果为正则为1,否则0
- ZR 零
- 运算结果为0则为1,否则0
- AC 辅助进位
- 低4位向高位进位1,否则0
- PE 奇偶校验
- 最低16位中含1的个数为偶数为1,否则0
- CY 进位
- 最高位进位1,否则0
常用指令
此处介绍汇编的常用基础指令,不做过多展开,仅记录基本含义
指令 | 作用 | e.g. |
---|---|---|
add | 加法 | add eax, ebx; |
and | 按位与操作 | and eax, ebx; |
call | 下一条指令地址入栈,跳到目标进行指令执行 | call 地址; |
cmp | 操作数1-(符号扩展)操作数2 不保存,观察标志位 | cmp eax, ebx; |
dec | 自减 | dec eax; |
div | 除法 结果,余数 (不同参数不同) | div bx; |
imul | 乘法 (不同参数不同) | imul eax, ebx, ecx; |
inc | 自增 | inc eax; |
jmp | 跳转 | 这是一系列指令 |
lea | 加载地址 | lea eax, 地址; |
mov | mov eax, 114514; | |
movsd | 双精度赋值到寄存器 | |
movss | 但精度数赋值到浮点寄存器 | |
movsx/movsxd | 符号扩展传输 | |
movs系列 | 批量内存传输 | |
movzx | 0扩 展传输 | |
neg | 取反(±) | neg eax; |
not | 按位取反 | not eax; |
or | 按照位或 | or eax, ebx; |
pop及相关 | 出栈 | pop eax; |
push及相关 | 入栈 | push eax; |
rcl | 循环左移 最高位到cf,cf移入最低位 | rcl eax, 次数; |
rcr | 循环右移 cf填入最高位,最低位填入cf | rcr eax, 次数; |
ret | 从栈中恢复地址 | ret ; |
rol | 循环左移 最高位到cf和最低位,cf原值丢弃 | rol eax, 次数; |
ror | 循环右移 最低位填入最高和cf | ror eax, 次数 |
sar | 算数右移 符号位保留 | sar eax, 数值; |
shr | 逻辑右移 高位补0 | shr eax, 次数 |
sub | 减法 | sub eax, ebx; |
test | 按位与 不保存,观察标志位 | cmp eax, ebx; |
xor | 按位异或 | xor eax, ebx; |
vs配置
寄存器
进入debug模式后,在顶部调试->窗口->寄存器
反汇编
在编辑界面,右击->转到反汇编
进入后右击选择显示具体信息
检测变量
注意设置不开优化