代码之家  ›  专栏  ›  技术社区  ›  paxdiablo

如何在gcc中获得完整的汇编程序输出?

  •  5
  • paxdiablo  · 技术社区  · 14 年前

    我知道我能找到装配工 来源 编译器生成的代码使用:

    gcc -S ...
    

    尽管这让人恼火,但作为过程的一部分,它并没有给我一个对象文件。

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

    输出的指令 gcc -S 不要告诉我任何关于指令长度或编码的事情,这是我想看到的。

    5 回复  |  直到 14 年前
        1
  •  9
  •   Matthew Slattery    14 年前

    我喜欢 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 --prefix-addresses -dr some_object.o 给予:

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

    但事实证明,您可以通过提供 另一个 模糊的选择,终于到达我的最爱 反汇编 咒语:

    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
  •  3
  •   Chris Dodd    14 年前

    获得快速列表的最简单方法是使用 -a 汇编程序的选项,您可以通过 -Wa,-a gcc 命令行。您可以使用选项的各种修改器来精确地影响结果——参见as(1)手册页。

        3
  •  1
  •   Jerry Coffin    14 年前

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

        4
  •  0
  •   Carl Norum    14 年前

    我觉得你想要一个拆卸器。 objdump 基本上是标准的( otool 在mac os x上);与链接器提供的任何映射文件信息一致,对象文件的反汇编应该提供您想要的一切。

        5
  •  0
  •   john    14 年前
    nasm -f elf xx.asm -l x.lst
    
    gcc xx.c xx.o -o xx
    

    生成仅用于x x.asm的“list”文件x.lst

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

    推荐文章