【问题标题】:How do I get full assembler output in gcc?如何在 gcc 中获得完整的汇编程序输出?
【发布时间】:2010-09-07 03:39:43
【问题描述】:

我知道我可以通过以下方式获得编译器生成的汇编器源代码

gcc -S ...

尽管这很烦人并没有给我一个目标文件作为过程的一部分。

但是我怎样才能获得有关编译代码的所有信息?我的意思是地址、生成的字节等等。

gcc -S 输出的指令没有告诉我任何关于指令长度或编码的信息,这是我想看到的。

【问题讨论】:

标签: gcc assembly opcode


【解决方案1】:

我喜欢 objdump 这一点,但最有用的选项并不明显 - 特别是如果您在包含重定位的目标文件上使用它,而不是最终的二进制文件。

objdump -d some_binary 做得很合理。

objdump -d some_object.o 用处不大,因为对外部函数的调用不会被反汇编:

...
00000005 <foo>:
   5:   55                      push   %ebp
   6:   89 e5                   mov    %esp,%ebp
   8:   53                      push   %ebx
...
  29:   c7 04 24 00 00 00 00    movl   $0x0,(%esp)
  30:   e8 fc ff ff ff          call   31 <foo+0x2c>
  35:   89 d8                   mov    %ebx,%eax
...

call 实际上是printf()...添加-r 标志有助于解决此问题;它标志着搬迁。 objdump -dr some_object.o 给:

...
  29:   c7 04 24 00 00 00 00    movl   $0x0,(%esp)
                        2c: R_386_32    .rodata.str1.1
  30:   e8 fc ff ff ff          call   31 <foo+0x2c>
                        31: R_386_PC32  printf
...

然后,我发现将每一行注释为&lt;symbol+offset&gt; 很有用。 objdump 有一个方便的选项,但它具有关闭实际字节转储的烦人副作用 - objdump --prefix-addresses -dr some_object.o 给出:

...
00000005 <foo> push   %ebp
00000006 <foo+0x1> mov    %esp,%ebp
00000008 <foo+0x3> push   %ebx
...

但事实证明,您可以通过提供另一个模糊选项来撤消该操作,最终得到我最喜欢的objdump 咒语:

objdump --prefix-addresses --show-raw-insn -dr file.o

输出如下:

...
00000005 <foo> 55                       push   %ebp
00000006 <foo+0x1> 89 e5                        mov    %esp,%ebp
00000008 <foo+0x3> 53                           push   %ebx
...
00000029 <foo+0x24> c7 04 24 00 00 00 00        movl   $0x0,(%esp)
                        2c: R_386_32    .rodata.str1.1
00000030 <foo+0x2b> e8 fc ff ff ff              call   00000031 <foo+0x2c>
                        31: R_386_PC32  printf
00000035 <foo+0x30> 89 d8                       mov    %ebx,%eax
...

如果您使用调试符号构建(即使用-g 编译),并且将-dr 替换为-Srl,它将尝试使用相应的源代码行注释输出。

【讨论】:

    【解决方案2】:

    获得快速列表的最简单方法是使用汇编程序的-a 选项,您可以通过在gcc 命令行上输入-Wa,-a 来实现。您可以对 a 选项使用各种修饰符来准确影响结果 - 请参阅 as(1) 手册页。

    【讨论】:

      【解决方案3】:

      听起来你想要一个反汇编程序。 objdump 几乎是标准的(otool 在 Mac OS X 上);与链接器为您提供的任何映射文件信息相一致,目标文件的反汇编应该为您提供所需的一切。

      【讨论】:

        【解决方案4】:

        gcc 将生成一个汇编语言源文件。然后,您可以使用as -a yourfile.S 生成一个列表,其中包括每条指令的偏移量和编码字节。 -a 也有一些子选项来控制列表文件中显示的内容(as --help 将提供它们的列表以及其他可用选项)。

        【讨论】:

          【解决方案5】:
          nasm -f elf xx.asm -l x.lst
          
          gcc xx.c xx.o -o xx
          

          生成一个“列表”文件 x.lst,它只用于 xx.asm

          对于 xx.c 和 xx.asm,您可以同时编译它们,然后使用 'gdb' - gnu 调试器

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-08-25
            • 2010-11-21
            • 2015-01-26
            • 1970-01-01
            • 2011-03-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多