5

我想知道究竟.cfi_remember_state是如何实现的。我知道它是一个伪操作,所以我想它在组装时会转换成几条指令。我很感兴趣使用什么确切的指令来实现它。我尝试了很多方法来弄清楚。即:

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

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

4

1 回答 1

3

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

DW_CFA_remember_state 指令不接受操作数。所需的操作是将每个寄存器的规则集推送到隐式堆栈中。

您可以使用 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

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

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 等调试器处理变量位置、堆栈信息等时使用这些伪指令。

于 2013-01-29T12:20:25.907 回答