.cfi_remember_state的实现

时间:2013-01-29 11:55:19

标签: gcc assembly x86 x86-64 gas

我想知道.cfi_remember_state到底是如何实现的。我知道这是一个伪操作,所以我想它在组装时会转换成几条指令。我感兴趣的是用于实现它的确切指令。我尝试了很多方法来弄明白。即:

  • 阅读GAS源代码。但未能找到足够有用的东西。
  • 阅读GAS文档。但是.cfi_remember_state条目只是一个简单的笑话(字面意思)。
  • 试图找到一个gcc开关,它会使gcc从C代码生成asm,伪操作“扩展”。无法为x86 / x86-64找到这样的开关。 (如果有人能指出我这样的转换,假设它存在,BTW会很好。)
  • Google-fu&&在SO上搜索并没有产生任何有用的东西。

在我看来,唯一的另一个解决方案是读取已组装的可执行文件的二进制文件并尝试推断出指令。但我想避免这样一项艰巨的任务。 有谁知道,启发我,它是如何在x86和/或x86-64上实现的?也许与分享获取信息的方式/位置一起,如果我有需要,我可以检查其他伪操作吗?

1 个答案:

答案 0 :(得分:3)

该指令是DWARF信息的一部分(实际上它只是发出DW_CFA_remember_state指令)。摘自DWARF3标准:

  

DW_CFA_remember_state指令不使用操作数。所需   action是将每个寄存器的规则集推送到隐式   叠加。

您可以使用objdump播放DWARF信息。让我们从简单的void汇编程序文件开始:

  .text
.globl main
  .type main, @function
main:
.LFB0:
.cfi_startproc
#.cfi_remember_state
.cfi_endproc
.LFE0:
  .size main, .-main

使用gcc cfirem.s -c -o cfirem.o

进行编译

现在用objdump --dwarf cfirem.o反汇编生成的DWARF部分 你会得到:

00000018 00000014 0000001c FDE cie=00000000 pc=00000000..00000000
  DW_CFA_nop
  DW_CFA_nop
  ...

如果你要取消注释.cfi_remember_state,你会看到:

00000018 00000014 0000001c FDE cie=00000000 pc=00000000..00000000
  DW_CFA_remember_state
  DW_CFA_nop
  DW_CFA_nop
  ...

所以它并没有真正转换为汇编程序指令(尝试objdump -d看到我们的示例中根本没有汇编程序指令)。它在DWARF伪指令中转换,在GDB之类的调试器处理变量位置,堆栈信息等时使用。