汇编代码能力
在as汇编中,以.开头的语句为汇编命令(或称为伪指令、指示符)
8个通用寄存器介绍:
eax:累加器(Accumulator)
ebx:基地址寄存器(Base Register)
ecx:计数寄存器(Count)
edx:数据寄存器(Data Register)
ebp:堆栈基指针(Base Pointer)
esi和edi:变址寄存器(Index Register)
esp:堆栈顶指针(Stack Pointer)
6个段寄存器:
CS 代码段、SS? stack segment、DS? 数据段、ES??数据段、FS??数据段、GS??数据段
1个状态寄存器:EFLAGS
1个指令寄存器:EIP
80386的寄存器,共16个,8个通用(如前所述)、段寄存器(6个)、状态寄存器和指令寄存器
堆栈回溯:
- 需要一个专门寄存器ebp来保存frame poniter。
- 保存ebp寄存器即保存回溯信息(unwind info)的动作会被编译成代码,有指令开销。
- 在回溯堆栈时,除了恢复sp,不知道怎么恢复其他的寄存器
调试信息标准DWARF(Debugging With Attributed Record Formats)定义了一个.debug_frame section用来解决上述的难题
- 可以把ebp当成常规寄存器使用。
- 但是当保存esp时,它必须在.debug_frame节中产生一条注释,告知调试器它将其保存在什么位置以及存放在何处。
- 这种机制还有的好处是它不仅仅是用来恢复ebp,还可以用来恢复其他寄存器。
- 而且是带外的,不消耗任何指令周期,没有任何性能开销。
但是.debug_frame面临一个难题:怎么样生成堆栈信息表?
为了解决上述难题,GAS(GCC Assembler)汇编编译器定义了一组伪指令来协助生成调用栈信息CFI(Call Frame Information)。CFI directives伪指令是一组生成CFI调试信息的高级语言
下表展示的是16bit寄存器 , 32bit寄存器的前缀是 e, 64bit的寄存器前缀是 r。
【编译、链接、装载五】编译器后端——gcc生成的汇编代码_cfi_startproc-CSDN博客
子函数使用之前将这些寄存器的值保存在栈中,待子函数使用完成后,再将栈中保存的值还给寄存器。根据谁负责保存这些寄存器,可以把它们分为两类:“调用者保存”和“被调用者保存”。“调用者保存”(caller-saved):即在调用子函数之前,将父函数用过的寄存器压栈;“被调用者保存”:即在子函数内,对即将使用的寄存器压栈。?
调用者保存寄存器 | 被调用者保存寄存器 |
---|---|
%r10,%r11 | %rbx, %rbp, %r12-15 |
如何编译不带:调试用的调用堆栈的
gcc -S hello.c -o hello.s -fno-asynchronous-unwind-tables?
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!