7

我知道我可以使用以下方法获取编译器生成的汇编代码:

gcc -S ...

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

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

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

4

5 回答 5

11

我喜欢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
...

然后,我发现将每一行注释为<symbol+offset>. 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它将尝试用相应的源代码行注释输出。

于 2010-09-07T23:27:31.650 回答
3

获得快速列表的最简单方法是使用-a汇编程序的选项,您可以通过-Wa,-agcc命令行中执行此操作。您可以对 a 选项使用各种修饰符来准确影响结果——参见 as(1) 手册页。

于 2010-09-08T00:27:48.853 回答
1

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

于 2010-09-07T03:53:20.277 回答
1

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

于 2010-09-07T03:53:25.427 回答
0
nasm -f elf xx.asm -l x.lst

gcc xx.c xx.o -o xx

生成仅用于 xx.asm 的“列表”文件 x.lst

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

于 2010-09-07T21:55:23.507 回答