汇编代码能力

发布时间:2023年12月19日

在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?

文章来源:https://blog.csdn.net/feelinglikeyou/article/details/135076746
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。