7

这接近于使用 GCC 生成可读的程序集?,但我在这里的上下文是avr-gcc(并且相应地,avr-objdump)Atmel(虽然,我想它会适用于整个 GCC 董事会)。

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

  • 我可以使用开关指示gcc发出汇编列表源(参见Linux 汇编和反汇编介绍) ;-S在这种情况下,我得到一个文件,其内容如下:
    ...
    环形:
      推r14
      推r15
      推r16
      推r17
      推r28
      推r29
    /* 序言:函数/
    /帧大小 = 0 */
      ldi r24,lo8(13)
      ldi r22,lo8(1)
      调用数字写入
      rjmp .L2
    .L3:
      ldi r24,lo8(MyObj)
      ldi r25,hi8(MyObj)
      调用 _ZN16MYOBJ7connectEv
    .L2:
      ldi r24,lo8(MyObj)
      ldi r25,hi8(MyObj)
      调用 _ZN16MYOBJ11isConnectedEv
    ...
    

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

  • 我可以检查最终的可执行文件,并指示objdump使用-S开关发出汇编列表源;在这种情况下,我得到一个文件,其内容如下:
    ...
    0000066a <初始化>:
    无效初始化()
    {
            // 这需要在 setup() 之前调用,否则某些函数不会
            //在那里工作
            sei();
         66a: 78 94 塞
         66c: 83 b7 在 r24, 0x33 ; 51
         66e: 84 60 ori r24, 0x04 ; 4
         670: 83 bf out 0x33, r24 ; 51
    ...
    000006be <循环>:
         6be: ef 92 推 r14
         6c0: ff 92 推 r15
         6c2: 0f 93 推 r16
         6c4: 1f 93 推 r17
         6c6:cf 93 推 r28
         6c8: df 93 推 r29
         6ca: 8d e0 ldi r24, 0x0D ; 13
         6cc: 61 e0 ldi r22, 0x01 ; 1
         6ce: 0e 94 23 02 调用 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 调用 0xc4a ;0xc4a <_ZN16MYOBJ7connectEv>
         6dc: 8d ef ldi r24, 0xFD ; 253
         6de: 94 e0 ldi r25, 0x04 ; 4
         6e0: 0e 94 21 06 调用 0xc42 ;0xc42 <_ZN16MYOBJ11isConnectedEv>
    ...
    

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

显然,两个列表(loop至少对于函数而言)代表相同的汇编代码;除了:

  • 一个gcc(应该)编译——objdump一个不编译
  • 一个包含所有引用函数的objdump列表,这些函数可以在“主”以外的文件中定义(例如,digitalWrite)——gcc一个没有
  • 一个包含原始的objdumpC/C++ 源代码行“散布”与程序集(但只是偶尔,而且似乎只适用于 C 文件?) -gcc一个

那么,有没有办法获得一个“可编译”的程序集列表,但是具有所有内联函数,并且源 C/C++ 代码(可能在适当的情况下)作为注释散布在其中(因此它们不会干扰与汇编文件的编译)?(没有为 的输出编写解析器objdump,即:)

4

3 回答 3

1

将选项添加-fverbose-asm到您的 gcc 命令行。(这在 gcc 手册中,但它记录在“代码生成选项”下)

于 2011-08-04T18:35:45.977 回答
1

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

也许你应该告诉我们你真正想要达到的目标,因为我认为这样的练习本身没有多大意义。

于 2011-08-05T10:41:17.793 回答
1

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

于 2011-08-31T20:20:50.747 回答