GCC / objdump:生成可编译/可构建的程序集(穿插在C / C ++中)源代码?

时间:2011-08-04 18:16:33

标签: c gcc assembly objdump

这接近Using GCC to produce readable assembly?,但我的上下文是Atmel的avr-gcc(相应地,avr-objdump)(不过,我想它会适用于GCC董事会)。

问题是,我有一个包含多个.c和.cpp文件的项目;最终被编译成可执行文件,其名称与'master'.cpp文件相同。在这个过程中,我可以通过两种方式获得汇编列表:

  • 我可以使用gcc开关指示-S发出汇编列表来源(请参阅Linux Assembly and Disassembly an Introduction);在这种情况下,我得到一个文件,内容如:
    ...
    loop:
      push r14
      push r15
      push r16
      push r17
      push r28
      push r29
    /* prologue: function /
    / frame size = 0 */
      ldi r24,lo8(13)
      ldi r22,lo8(1)
      call digitalWrite
      rjmp .L2
    .L3:
      ldi r24,lo8(MyObj)
      ldi r25,hi8(MyObj)
      call _ZN16MYOBJ7connectEv
    .L2:
      ldi r24,lo8(MyObj)
      ldi r25,hi8(MyObj)
      call _ZN16MYOBJ11isConnectedEv
    ...
    

尚未尝试过;但我猜这段代码是可编译的/可构建的......

  • 我可以使用objdump开关检查最终的可执行文件,并指示-S发出汇编列表源;在这种情况下,我得到一个文件,内容如:
    ...
    0000066a <init>:
    void init()
    {
            // this needs to be called before setup() or some functions won't
            // work there
            sei();
         66a:       78 94           sei
         66c:       83 b7           in      r24, 0x33       ; 51
         66e:       84 60           ori     r24, 0x04       ; 4
         670:       83 bf           out     0x33, r24       ; 51
    ...
    000006be <loop>:
         6be:       ef 92           push    r14
         6c0:       ff 92           push    r15
         6c2:       0f 93           push    r16
         6c4:       1f 93           push    r17
         6c6:       cf 93           push    r28
         6c8:       df 93           push    r29
         6ca:       8d e0           ldi     r24, 0x0D       ; 13
         6cc:       61 e0           ldi     r22, 0x01       ; 1
         6ce:       0e 94 23 02     call    0x446   ; 0x446 
         6d2:       04 c0           rjmp    .+8             ; 0x6dc 
         6d4:       8d ef           ldi     r24, 0xFD       ; 253
         6d6:       94 e0           ldi     r25, 0x04       ; 4
         6d8:       0e 94 25 06     call    0xc4a   ; 0xc4a <_ZN16MYOBJ7connectEv>
         6dc:       8d ef           ldi     r24, 0xFD       ; 253
         6de:       94 e0           ldi     r25, 0x04       ; 4
         6e0:       0e 94 21 06     call    0xc42   ; 0xc42 <_ZN16MYOBJ11isConnectedEv>
    ...
    

我确实尝试构建此代码,但确实失败了 - 它将'行号'作为标签读取)

显然,两个列表(至少为loop函数)代表相同的汇编代码;不同的是:

  • gcc一个(应该)编译 - objdump一个
  • objdump包含所有引用函数的列表,这些函数可以在“master”以外的文件中定义(例如digitalWrite) - gcc一个
  • objdump一个包含原始的C / C ++源代码行'散布'与汇编(但只是偶尔,似乎只针对C文件?) - gcc一个不< /强>

那么,有没有办法获得一个“可编译”的汇编列表,但是对于所有内联函数,以及源C / C ++代码(可能在适当的地方)穿插作为注释(所以他们不要不干扰汇编文件的编译)? (没有为objdump的输出编写解析器,即:)

3 个答案:

答案 0 :(得分:1)

将选项-fverbose-asm添加到您的gcc命令行。 (这是在gcc手册中,但它在'Code Gen Options'中记录)

答案 1 :(得分:1)

您所谈论的“依赖关系”通常来自库或单独的目标文件,因此它们没有源 - 它们只是作为二进制代码链接到最终的可执行文件中。由于此类代码不通过汇编程序传递,因此您必须使用其他方式提取它 - 例如使用objdump。

也许你应该告诉我们你真正想要实现的目标,因为我自己并没有看到这样的练习。

答案 2 :(得分:1)

我能够获得的最好效果是使用-Wa,-ahl=outfile.s代替-S。它不是可编译的代码,而是用于诊断目的的列表文件;编译的目标文件照常发出。