43

How do I compile to assembly instead of an executable with gcc. I know there is an -S flag, but where do I use it in the makefile. For example, if I use flags -O3 -o exe_name, where should I put the -S flag?

MetallicPriest
  • 29,191
  • 52
  • 200
  • 356

3 Answers3

58

I suggest also using -fverbose-asm because then the generated assembler has some generated comments which "explains" the code. For example:

gcc -S -fverbose-asm -O2 foo.c

would generate in foo.s (with some comments) the assembler code produced by compiling foo.c

And to understand what the GCC optimizations are doing one could even try -fdump-tree-all (but this produces hundreds of files!).

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • 3
    Related: [How to remove "noise" from GCC/clang assembly output?](https://stackoverflow.com/q/38552116) for more ways to make asm more readable, and an excellent intro video to reading x86 asm, from Matt Godbolt (of online compiler-explorer fame). – Peter Cordes Jul 04 '18 at 13:13
30

You can ask GCC to produce the assembly file, instead of an object file (or an executable).

For instance:

gcc -Wall -c test.c

Will produce an object file from test.c (test.o).

gcc -Wall -o test test.c

Will produce an executable file named 'test' from test.c

gcc -Wall -S test.c

Will produce an assembly file from test.c (test.s)

Macmade
  • 52,708
  • 13
  • 106
  • 123
  • 9
    Respectfully disagree: you do *compile* to assembly, then *assemble* to an object file. For instance, the documentation for `-S` on my system says `Stop after the stage of compilation proper; do not assemble.` – Frédéric Hamidi Nov 05 '11 at 17:29
  • 2
    Why do you say you don't "compile" to assembly? That's exactly what it is doing! Compiling! To machine code aka assembly! After compiling, it's just a matter of writing it in 0-1s or letters. – Shahbaz Nov 05 '11 at 17:30
  • 2
    In my opinion, compilation means to turn source code into machine code. Assembly is source code, even if very close to machine code. – Macmade Nov 05 '11 at 17:33
  • 4
    @Macmade, compilation can also mean to turn high-level language constructs into low-level opcodes (that, incidentally, can be represented in assembly then converted to machine code). Your mileage may vary (especially with "managed" languages like C#, which compile to CIL then JIT to machine code). – Frédéric Hamidi Nov 05 '11 at 17:36
  • @Macmade, Isn't the assembly file output from `-S` just a normal text file? – Pacerier Mar 03 '17 at 20:22
  • 1
    @Pacerier Yes, so? – Macmade Mar 06 '17 at 01:30
  • 1
    @Macmade: for the record, gcc is designed so that the actual compiler (`cc1`) produces asm, which is assembled by a separate assembler. With `-o`, the front end does this for you, but it is a separate step. There is no option to go *directly* to machine code, because gcc doesn't have an assembler built-in. An assembler has to know about object-file formats (ELF, A.OUT, Mach-O, Windows PE, etc.), instruction encoding optimization, branch-displacement optimization, etc. gcc doesn't even know instruction lengths, it just has heuristics for emitting `.p2align 4,12` / `.p2align 3` for example. – Peter Cordes Jul 04 '18 at 13:11
14

Put it pretty much anywhere.

gcc -O3 -S -o output.asm ...

will store the generated assemby in output.asm.

Mat
  • 202,337
  • 40
  • 393
  • 406