Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GCC/objdump: Generating compilable/buildable assembly (interspersed with C/C++) source?

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 :))

like image 928
sdaau Avatar asked Aug 04 '11 18:08

sdaau


People also ask

How do you get assembler output from C C++ source in gcc?

Here we will see how to generate assembler output from C or C++ code using gcc. The gcc provides a great feature to get all intermediate outputs from a source code while executing. To get the assembler output we can use the option '-S' for the gcc.

What is Objdump in GCC?

objdump is a command-line program for displaying various information about object files on Unix-like operating systems. For instance, it can be used as a disassembler to view an executable in assembly form. It is part of the GNU Binutils for fine-grained control over executables and other binary data.

Can C compile to assembly?

Compilers for high-level languages like C/C++ have the ability to translate high-level language into assembly code. The GNU C and C++ Compiler option of -S will generate an assembly code equivalent to that of the corresponding source program.


2 Answers

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')

like image 57
Spudd86 Avatar answered Oct 26 '22 12:10

Spudd86


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.

like image 43
Igor Skochinsky Avatar answered Oct 26 '22 11:10

Igor Skochinsky