Using GCC to produce readable assembly?

后端 未结 10 1947
死守一世寂寞
死守一世寂寞 2020-11-22 06:13

I was wondering how to use GCC on my C source file to dump a mnemonic version of the machine code so I could see what my code was being compiled into. You can do this with J

相关标签:
10条回答
  • 2020-11-22 07:01

    Use the -S (note: capital S) switch to GCC, and it will emit the assembly code to a file with a .s extension. For example, the following command:

    gcc -O2 -S foo.c

    will leave the generated assembly code on the file foo.s.

    Ripped straight from http://www.delorie.com/djgpp/v2faq/faq8_20.html (but removing erroneous -c)

    0 讨论(0)
  • 2020-11-22 07:02

    Using the -S switch to GCC on x86 based systems produces a dump of AT&T syntax, by default, which can be specified with the -masm=att switch, like so:

    gcc -S -masm=att code.c
    

    Whereas if you'd like to produce a dump in Intel syntax, you could use the -masm=intel switch, like so:

    gcc -S -masm=intel code.c
    

    (Both produce dumps of code.c into their various syntax, into the file code.s respectively)

    In order to produce similar effects with objdump, you'd want to use the --disassembler-options= intel/att switch, an example (with code dumps to illustrate the differences in syntax):

     $ objdump -d --disassembler-options=att code.c
    
     080483c4 <main>:
     80483c4:   8d 4c 24 04             lea    0x4(%esp),%ecx
     80483c8:   83 e4 f0                and    $0xfffffff0,%esp
     80483cb:   ff 71 fc                pushl  -0x4(%ecx)
     80483ce:   55                      push   %ebp
     80483cf:   89 e5                   mov    %esp,%ebp
     80483d1:   51                      push   %ecx
     80483d2:   83 ec 04                sub    $0x4,%esp
     80483d5:   c7 04 24 b0 84 04 08    movl   $0x80484b0,(%esp)
     80483dc:   e8 13 ff ff ff          call   80482f4 <puts@plt>
     80483e1:   b8 00 00 00 00          mov    $0x0,%eax
     80483e6:   83 c4 04                add    $0x4,%esp 
     80483e9:   59                      pop    %ecx
     80483ea:   5d                      pop    %ebp
     80483eb:   8d 61 fc                lea    -0x4(%ecx),%esp
     80483ee:   c3                      ret
     80483ef:   90                      nop
    

    and

    $ objdump -d --disassembler-options=intel code.c
    
     080483c4 <main>:
     80483c4:   8d 4c 24 04             lea    ecx,[esp+0x4]
     80483c8:   83 e4 f0                and    esp,0xfffffff0
     80483cb:   ff 71 fc                push   DWORD PTR [ecx-0x4]
     80483ce:   55                      push   ebp
     80483cf:   89 e5                   mov    ebp,esp
     80483d1:   51                      push   ecx
     80483d2:   83 ec 04                sub    esp,0x4
     80483d5:   c7 04 24 b0 84 04 08    mov    DWORD PTR [esp],0x80484b0
     80483dc:   e8 13 ff ff ff          call   80482f4 <puts@plt>
     80483e1:   b8 00 00 00 00          mov    eax,0x0
     80483e6:   83 c4 04                add    esp,0x4
     80483e9:   59                      pop    ecx
     80483ea:   5d                      pop    ebp
     80483eb:   8d 61 fc                lea    esp,[ecx-0x4]
     80483ee:   c3                      ret    
     80483ef:   90                      nop
    
    0 讨论(0)
  • 2020-11-22 07:03

    Use the -S (note: capital S) switch to GCC, and it will emit the assembly code to a file with a .s extension. For example, the following command:

    gcc -O2 -S -c foo.c

    0 讨论(0)
  • 2020-11-22 07:05

    If you compile with debug symbols, you can use objdump to produce a more readable disassembly.

    >objdump --help
    [...]
    -S, --source             Intermix source code with disassembly
    -l, --line-numbers       Include line numbers and filenames in output
    

    objdump -drwC -Mintel is nice:

    • -r shows symbol names on relocations (so you'd see puts in the call instruction below)
    • -R shows dynamic-linking relocations / symbol names (useful on shared libraries)
    • -C demangles C++ symbol names
    • -w is "wide" mode: it doesn't line-wrap the machine-code bytes
    • -Mintel: use GAS/binutils MASM-like .intel_syntax noprefix syntax instead of AT&T
    • -S: interleave source lines with disassembly.

    You could put something like alias disas="objdump -drwCS -Mintel" in your ~/.bashrc


    Example:

    > gcc -g -c test.c
    > objdump -d -M intel -S test.o
    
    test.o:     file format elf32-i386
    
    
    Disassembly of section .text:
    
    00000000 <main>:
    #include <stdio.h>
    
    int main(void)
    {
       0:   55                      push   ebp
       1:   89 e5                   mov    ebp,esp
       3:   83 e4 f0                and    esp,0xfffffff0
       6:   83 ec 10                sub    esp,0x10
        puts("test");
       9:   c7 04 24 00 00 00 00    mov    DWORD PTR [esp],0x0
      10:   e8 fc ff ff ff          call   11 <main+0x11>
    
        return 0;
      15:   b8 00 00 00 00          mov    eax,0x0
    }
      1a:   c9                      leave  
      1b:   c3                      ret
    
    0 讨论(0)
提交回复
热议问题