这两天的pwn题环境都是在Linux中,采用的汇编语言是 AT&T 格式。之前学习的是Intel格式的8086汇编,今天学习了下AT&T汇编语言。
1、汇编指令
基于 x86 架构 的处理器所使用的汇编指令一般有两种格式:
- Intel 汇编:DOS(8086处理器)、Windows
- AT&T汇编:Linux, Unix, Mac OS,
2、AT&T与Intel 汇编语法
操作 | Intel格式 | AT&T格式 |
---|---|---|
寄存器命名 | push eax | pushl %eax |
常数\立即操作数 | push 50 | pushl $50 |
操作数顺序 | 操作数排列是从源(右)到目的(左),如add eax(目的),edx(源)(eax=eax+edx) | 操作数排列是从源(左)到目的(右),如add %edx(源),%eax(目的)(%eax=%eax+%edx) |
操作数的字长 | 后缀b、w、l分别表示操作数为字节(byte,8 比特)、字(word,16 比特)和长字(long,32比特) | 用前缀byte ptr 和 word ptr表示 |
绝对转移指令jmp | jmp eax | 操作数前要加上'*'作为前缀,如jmp *eax |
调用指令call | call eax | 操作数前要加上'*'作为前缀,如call *eax |
内存引用 | section:[base+index*scale+displacement] | section:displacement(base,index,scale) |
远程转移指令 | jmp far section:offset | ljump $section, $offset |
远程子调用指令 | lcall $section, $offset | call far section:offset |
内存操作数 | mov ebx, [ebp - 3] | movl -3(%ebp), %ebx |
3、函数的调用流程(内存)
- push 参数
- push 函数的返回地址
- push bp (保留bp之前的值,方便以后恢复)
- mov bp, sp (保留sp之前的值,方便以后恢复)
- sub sp,空间大小 (分配空间给局部变量)
- 保护可能要用到的寄存器
- 使用CC(int 3)填充局部变量的空间
- --------执行业务逻辑--------
- 恢复寄存器之前的值
- mov sp, bp (恢复sp之前的值)
- pop bp (恢复bp之前的值)
- ret (将函数的返回地址出栈,执行下一条指令)
- 恢复栈平衡 (add sp,参数所占的空间)