7
votes

This is close to Using GCC to produce readable assembly?, but my context here is avr-gcc (and correspondingly, avr-objdump) for Atmel (though, I guess it would apply across the GCC board).

The thing is, I have a project of multiple .c and .cpp files; which ultimately get compiled into an executable, with the same name as the 'master' .cpp file. In this process, I can obtain assembly listing in two ways:

  • I can instruct gcc to emit assembly listing source (see Linux Assembly and Disassembly an Introduction) using the -S switch; in this case, I get a file, with contents like:
    ...
    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
    ...
    

(Haven't tried it yet; but I guess this code is compilable/buildable....)

  • I can inspect the final executable with, and instruct, objdump to emit assembly listing source using the -S switch; in this case, I get a file, with contents like:
    ...
    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>
    ...
    

(I did try to build this code, and it did fail - it reads the 'line numbers' as labels)

Obviously, both listings (for the loop function, at least) represent the same assembly code; except:

  • The gcc one (should) compile -- the objdump one does not
  • The objdump one contains listings of all referred functions, which could be defined in files other than the 'master' (e.g., digitalWrite) -- the gcc one does not
  • The objdump one contains original C/C++ source lines 'interspersed' with assembly (but only occasionally, and seemingly only for C files?) -- the gcc one does not

So, is there a way to obtain an assembly listing that would be 'compilable', however with all in-linked functions, and where source C/C++ code is (possibly, where appropriate) interspersed as comments (so they don't interfere with compilation of assembly file)? (short of writing a parser for the output of objdump, that is :))

3

3 Answers

1
votes

Add the option -fverbose-asm to your gcc command line up there. (This is in the gcc manual, but it's documented under 'Code Gen Options')

1
votes

The "dependencies" that you talk about often come from libraries or separate object files, so they don't have a source - they're just linked as binary code into the final executable. Since such code is not passed through the assembler, you will have to extract it using other ways - e.g. using objdump.

Maybe you should tell us what you really want to achieve because I don't see much point in such an exercise by itself.

1
votes

The best I have been able to get is to use -Wa,-ahl=outfile.s instead of -S. It isn't compilable code though, but a listing file for diagnostic purposes; the compiled object file is emitted as usual.