本文用以记录常用汇编指令以供快速查找回忆,仅限于 X86_64 的 AT&T 格式。
语法格式
1. 引用寄存器前加 %。如
2. 指令长度后缀
对于访问内存的数据,指令后加上 b w l q,操作 1 2 4 8 字节。如
1 2 3 4
| movb $0x1,0x201c3f(%rip) nopw %cs:0x0(%rax,%rax,1) movl $0x5,-0xc(%rbp) movq $0x400b30,-0x18(%rbp)
|
3. 立即数前加 $。16 进制数用 0x 开头。如
1 2
| movl $1, %eax mov $0x0,%eax
|
4. 注释可以用 ! 开头,也可以用 ;
5. 操作数顺序
从源操作数到目的操作数,如下将 %rsp 寄存器中的数传给 %rbp 寄存器。
6. 数据声明
命令 |
数据类型 |
.ascii |
文本字符串 |
.asciz |
以空字符串结尾的文本字符串 |
.byte |
字节值 |
.double |
双精度浮点数 |
.float |
单精度浮点数 |
.single |
单精度浮点数同上 |
.int |
32位整数 |
.long |
32位整数同上 |
.octa |
16字节整数 |
.quad |
8字节整数 |
.short |
16位整数 |
.comm |
声明未初始化的数据的通用内存区域 |
.lcomm |
声明未初始化的数据的本地通用内存区域 |
7. 文件组成
命令 |
作用 |
.org |
定义当前汇编位置 |
.globl |
让段全局可见 |
.text |
存放代码指令正文段 |
.bss |
存放未初始化的全局和静态变量,运行时该区域初始化为 0 |
.rodata |
read only data |
.data |
可读可写的数据段 |
8. 寻址方式
- 间址寻址:把寄存器上的值所代表的地址所指向的值放到寄存器中
1 2
| movl $0x8000,%ebx movl (%ebx),%eax
|
- 基址寻址:以寄存器里的数值作为基址,加上一个常数得到最终地址,把地址上的值放到寄存器中
1 2
| movl $0x8000,%eax movl 4(%eax),%ebx
|
- 变址寻址:以两个寄存器里的数值之和加上一个常数得到最终地址,把地址上的值放到寄存器中
1 2 3 4
| movl $0x8000,%eax movl $0x4,%ebx movl (%eax,%ebx),%ecx movl 4(%eax,%ebx),%ecx
|
- 比例变址寻址:以一个寄存器里的数值加上另一个寄存器里的数字,乘以一个比例因子(1,2,4,8)再加上一个常数得到最终地址,把地址上的值放到寄存器中
1 2 3 4 5 6
| movl $0x2000,%eax movl $0x2,%ebx movl (,%eax,4),%ecx movl 6(,%eax,4), %ecx movl (%ebx,%eax,4),%ecx movl 6(%ebx,%eax,4),%ecx
|
常见指令
1. mov 用于将源操作数移动到目的操作数
2. add 用于将源操作数加给目的操作数
3. sub 用于将两个数相减
4. inc 用于加一
5. dec 用于减一
6. push 用于将数据压入栈
7. pop 用于将数据出栈
8. jmp 跳转
1 2 3 4 5 6 7 8 9 10 11
| jmp label je label jne label jg label jge label jl label jle label ja label jae label jb label jbe label
|
9. mul 乘法
1 2
| imull %eax,%ebx mull %eax,%ebx
|
10. div 除法
11. and 按位与
12. or 按位或
13. xor 按位异位
14. shl 和 sal 位左移
1 2
| shll $1,%eax sall $1,%eax
|
15. shr 和 sar 位右移
1 2
| shrl $1,%eax sarl $1,%eax
|
16. lea 装载有效地址
17. call 函数调用
18. ret 函数返回
19. test 与运算并设置标志寄存器
20. cmp 比较操作数大小
21. rep 重复执行指令直到某一条件
22. lock 锁定总线
23. xadd 交换两个操作数值,使他们相加
24. nop 空操作
25. hlt 使处理器暂停直到收到中断信号
26. xchg 交换两个操作数的值
27. cld 清除方向寄存器(DF)
28. movsb 移动字符串
29. scasb 查找字符
30. cli 禁用所有中断