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

后端 未结 17 1812
天命终不由人
天命终不由人 2020-11-22 02:43

How does one do this?

If I want to analyze how something is getting compiled, how would I get the emitted assembly code?

相关标签:
17条回答
  • 2020-11-22 02:57

    Use the -S option:

    gcc -S program.c
    
    0 讨论(0)
  • 2020-11-22 02:58

    -save-temps

    This was mentioned at https://stackoverflow.com/a/17083009/895245 but let me further exemplify it.

    The big advantage of this option over -S is that it is very easy to add it to any build script, without interfering much in the build itself.

    When you do:

    gcc -save-temps -c -o main.o main.c
    

    main.c

    #define INC 1
    
    int myfunc(int i) {
        return i + INC;
    }
    

    and now, besides the normal output main.o, the current working directory also contains the following files:

    • main.i is a bonus and contains the preprossessed file:

      # 1 "main.c"
      # 1 "<built-in>"
      # 1 "<command-line>"
      # 31 "<command-line>"
      # 1 "/usr/include/stdc-predef.h" 1 3 4
      # 32 "<command-line>" 2
      # 1 "main.c"
      
      
      int myfunc(int i) {
          return i + 1;
      }
      
    • main.s contains the desired generated assembly:

          .file   "main.c"
          .text
          .globl  myfunc
          .type   myfunc, @function
      myfunc:
      .LFB0:
          .cfi_startproc
          pushq   %rbp
          .cfi_def_cfa_offset 16
          .cfi_offset 6, -16
          movq    %rsp, %rbp
          .cfi_def_cfa_register 6
          movl    %edi, -4(%rbp)
          movl    -4(%rbp), %eax
          addl    $1, %eax
          popq    %rbp
          .cfi_def_cfa 7, 8
          ret
          .cfi_endproc
      .LFE0:
          .size   myfunc, .-myfunc
          .ident  "GCC: (Ubuntu 8.3.0-6ubuntu1) 8.3.0"
          .section    .note.GNU-stack,"",@progbits
      

    If you want to do it for a large number of files, consider using instead:

     -save-temps=obj
    

    which saves the intermediate files to the same directory as the -o object output instead of the current working directory, thus avoiding potential basename conflicts.

    Another cool thing about this option is if you add -v:

    gcc -save-temps -c -o main.o -v main.c
    

    it actually shows the explicit files being used instead of ugly temporaries under /tmp, so it is easy to know exactly what is going on, which includes the preprocessing / compilation / assembly steps:

    /usr/lib/gcc/x86_64-linux-gnu/8/cc1 -E -quiet -v -imultiarch x86_64-linux-gnu main.c -mtune=generic -march=x86-64 -fpch-preprocess -fstack-protector-strong -Wformat -Wformat-security -o main.i
    /usr/lib/gcc/x86_64-linux-gnu/8/cc1 -fpreprocessed main.i -quiet -dumpbase main.c -mtune=generic -march=x86-64 -auxbase-strip main.o -version -fstack-protector-strong -Wformat -Wformat-security -o main.s
    as -v --64 -o main.o main.s
    

    Tested in Ubuntu 19.04 amd64, GCC 8.3.0.

    CMake predefined targets

    CMake automatically provides a targets for the preprocessed file:

    make help
    

    shows us that we can do:

    make main.s
    

    and that target runs:

    Compiling C source to assembly CMakeFiles/main.dir/main.c.s
    /usr/bin/cc    -S /home/ciro/hello/main.c -o CMakeFiles/main.dir/main.c.s
    

    so the file can be seen at CMakeFiles/main.dir/main.c.s

    Tested on cmake 3.16.1.

    0 讨论(0)
  • 2020-11-22 03:00

    As mentioned before, look at the -S flag.

    It's also worth looking at the '-fdump-tree' family of flags, in particular '-fdump-tree-all', which lets you see some of gcc's intermediate forms. These can often be more readable than assembler (at least to me), and let you see how optimisation passes perform.

    0 讨论(0)
  • 2020-11-22 03:01

    From: http://www.delorie.com/djgpp/v2faq/faq8_20.html

    gcc -c -g -Wa,-a,-ad [other GCC options] foo.c > foo.lst

    in alternative to PhirePhly's answer Or just use -S as everyone said.

    0 讨论(0)
  • 2020-11-22 03:03

    This will generate assembly code with the C code + line numbers interweaved, to more easily see which lines generate what code:

    # create assembler code:
    g++ -S -fverbose-asm -g -O2 test.cc -o test.s
    # create asm interlaced with source lines:
    as -alhnd test.s > test.lst
    

    Found in Algorithms for programmers, page 3 (which is the overall 15th page of the PDF).

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

    recently i wanted to know the assembly of each functions in a program
    this is how i did it.

    $ gcc main.c                      // main.c source file
    $ gdb a.exe                       // gdb a.out in linux
      (gdb) disass main               // note here main is a function
                                      // similary it can be done for other functions
    
    0 讨论(0)
提交回复
热议问题