• About
  • Contact
  • Cookie
  • Disclaimer
  • Privacy Policy
  • Change the purpose of use

Tnhelearning.edu.vn - Various useful general information portal

  • Photo
  • Bio
  • How To
  • Tech

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

March 2, 2024 by admin Category: Top

You are viewing the article How do you get assembler output from C/C++ source in GCC?  at Tnhelearning.edu.vn you can quickly access the necessary information in the table of contents of the article below.

How to set vs code for assembly code | How to run assembly code in without using any command
How to set vs code for assembly code | How to run assembly code in without using any command

How does one do this?

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

How does one do this?

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

Use the -S option to gcc (or g++), optionally with -fverbose-asm which works well at the default -O0 to attach C names to asm operands as comments. It works less well at any optimization level, which you normally want to use to get asm worth looking at.

gcc -S helloworld.c

This will run the preprocessor (cpp) over helloworld.c, perform the initial compilation and then stop before the assembler is run. For useful compiler options to use in that case, see How to remove “noise” from GCC/clang assembly output? (or just look at your code on Matt Godbolt’s online Compiler Explorer which filters out directives and stuff, and has highlighting to match up source lines with asm using debug information.)

By default, this will output the file helloworld.s. The output file can be still be set by using the -o option, including -o - to write to standard output for pipe into less.

gcc -S -o my_asm_output.s helloworld.c

Of course, this only works if you have the original source.
An alternative if you only have the resultant object file is to use objdump, by setting the --disassemble option (or -d for the abbreviated form).

objdump -S --disassemble helloworld > helloworld.dump

-S interleaves source lines with normal disassembly output, so this option works best if debugging option is enabled for the object file (-g at compilation time) and the file hasn’t been stripped.

Running file helloworld will give you some indication as to the level of detail that you will get by using objdump.

Other useful objdump options include -rwC (to show symbol relocations, disable line-wrapping of long machine code, and demangle C++ names). And if you don’t like AT&T syntax for x86, -Mintel. See the man page.

So for example, objdump -drwC -Mintel -S foo.o | less.
-r is very important with a .o that only has 00 00 00 00 placeholders for symbol references, as opposed to a linked executable.

.intel_syntaxis not compatible with NASM. It's more like MASM (e.g.
mov eax, symbolis a load, unlike in NASM where it's a
mov r32, imm32of the address), but not totally compatible with MASM either. I do highly recommend it as a nice format to read, especially if you like to write in NASM syntax though.
objdump -drwC -Mintel | lessor
gcc foo.c -O1 -fverbose-asm -masm=intel -S -o- | lessare useful. (See also How to remove “noise” from GCC/clang assembly output?).
-masm=intelworks with clang, too. Sep 2, 2017 at 19:27
gcc -O -fverbose-asm -SSep 21, 2017 at 9:02

This will generate assembly code with the C code + line numbers interwoven, to more easily see which lines generate what code (-S -fverbose-asm -g -O2):

# 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

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

  How to Make Our Hello World Usable as an Exploit Payload

ason OS X doesn't know these flags. If it did, though, you could probably one-line this using
-Wato pass options to
as.
g++ -g -O0 -c -fverbose-asm -Wa,-adhln test.cpp > test.lstwould be the short hand version of this. May 6, 2013 at 13:49
gcc -c -g -Wa,-ahl=test.s test.cor
gcc -c -g -Wa,-a,-ad test.c > test.txt
-O0? That's full of loads/stores that make it hard to track a value, and doesn't tell you anything about how efficient the optimized code will be. Jul 25, 2016 at 0:23

The following command line is from Christian Garbin’s blog:

g++ -g -O -Wa,-aslh horton_ex2_05.cpp >list.txt

I ran G++ from a DOS window on Windows XP, against a routine that contains an implicit cast

cd C:gpp_code g++ -g -O -Wa,-aslh horton_ex2_05.cpp > list.txt

Output:

horton_ex2_05.cpp: In function `int main()': horton_ex2_05.cpp:92: warning: assignment to `int' from `double'

The output is assembled generated code, interspersed with the original C++ code (the C++ code is shown as comments in the generated assembly language stream)

16:horton_ex2_05.cpp **** using std::setw; 17:horton_ex2_05.cpp **** 18:horton_ex2_05.cpp **** void disp_Time_Line (void); 19:horton_ex2_05.cpp **** 20:horton_ex2_05.cpp **** int main(void) 21:horton_ex2_05.cpp **** { 164 %ebp 165 subl $128,%esp ?GAS LISTING C:DOCUME~1CRAIGM~1LOCALS~1Tempccx52rCc.s 166 0128 55 call ___main 167 0129 89E5 .stabn 68,0,21,LM2-_main 168 012b 81EC8000 LM2: 168 0000 169 0131 E8000000 LBB2: 169 00 170 .stabn 68,0,25,LM3-_main 171 LM3: 172 movl $0,-16(%ebp)

-O2, or whatever optimization options you actually use when building your project, if you want to see how gcc optimizes your code. (Or if you use LTO, like you should, then you have to disassemble the linker output to see what you really get.) Oct 7, 2017 at 22:16

This was mentioned in METADATA’s answer, but let me further exemplify it.

READ More:   Graveler Pokédex: stats, moves, evolution & locations

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

#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 preprocessed 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.

  Using Retro Assembler with Visual Studio Code – Engine Designs

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

It was tested in Ubuntu 19.04 (Disco Dingo) amd64, GCC 8.3.0.

READ More:   Which Korean scented bag is the most fragrant? Top 5 Korean fragrance bag brands

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.

It was tested on CMake 3.16.1.

If what you want to see depends on the linking of the output, then objdump on the output object file/executable may also be useful in addition to the aforementioned gcc -S. Here’s a very useful script by Loren Merritt that converts the default objdump syntax into the more readable NASM syntax:

#!/usr/bin/perl -w $ptr='(BYTE|WORD|DWORD|QWORD|XMMWORD) PTR '; $reg='(?:[er]?(?:[abcd]x|[sd]i|[sb]p)|[abcd][hl]|r1?[0-589][dwb]?|mm[0-7]|xmm1?[0-9])'; open FH, '-|', '/usr/bin/objdump', '-w', '-M', 'intel', @ARGV or die; $prev = ""; while(<FH>){ if(/$ptr/o) { s/$ptr([[^[]]+],$reg)/$2/o or s/($reg,)$ptr([[^[]]+])/$1$3/o or s/$ptr/lc $1/oe; } if($prev =~ /t(repz )?ret / and $_ =~ /tnop |txchg *ax,ax$/) { # drop this line } else { print $prev; $prev = $_; } } print $prev; close FH;

I suspect this can also be used on the output of gcc -S.

mov eax,ds:0x804b794is not very NASMish. Also, sometimes it just strips useful information:
movzx eax,[edx+0x1]leaves the reader to guess whether the memory operand was
byteor
word.
objconv. You can get it to disassemble to stdout with output file =
/dev/stdout, so you can pipe into
lessfor viewing. There's also
ndisasm, but it only disassembles flat binaries, and doesn't know about object files (ELF / PE). Oct 7, 2017 at 22:12

Well, as everyone said, use the -S option.

If you use the -save-temps option, you can also get the preprocessed file (.i), assembly file (.s) and object file (*.o) (get each of them by using -E, -S, and -c, respectively).

If you’re looking for LLVM assembly:

llvm-gcc -emit-llvm -S hello.c

I don’t see this possibility among answers, probably because the question is from 2008, but in 2018 you can use Matt Goldbolt’s online website https://godbolt.org

You can also locally git clone and run his project https://github.com/mattgodbolt/compiler-explorer

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.

  Compile 6502 assembly code in VSCode on Mac, Linux, and Windows #6502 #Assembly #VSCode #Commodore

As everyone has pointed out, use the -S option to GCC. I would also like to add that the results may vary (wildly!) depending on whether or not you add optimization options (-O0 for none, -O2 for aggressive optimization).

READ More:   How to force restart your iPhone 12 or iPhone 12 Pro

On RISC architectures in particular, the compiler will often transform the code almost beyond recognition in doing optimization. It’s impressive and fascinating to look at the results!

Use the -S option:

gcc -S program.c

Here is a solution for C using GCC:

gcc -S program.c && gcc program.c -o output

Here the first part stores the assembly output of the program in the same file name as the program, but with a changed .s extension, you can open it as any normal text file.

The second part here compiles your program for actual usage and generates an executable for your Program with a specified file name.

The program.c used above is the name of your program and output is the name of the executable you want to generate.

gcc -O2 -save-temps foo.cto compile+assemble+link, but save the intermediate
.sand
.ofiles, instead of separately running a build that only compiles to asm. (But also a
.ipreprocessed C file). So it's fewer steps, but produces files you don't want. Oct 12, 2021 at 9:06

From the FAQ How to get GCC to generate assembly code:

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

as an alternative to PhirePhly’s answer.

Or just use -S as everyone said.

Recently I wanted to know the assembly of each functions in a. This is how I did it:

gcc main.c // 'main.c' source file gdb a.exe // 'gdb a.out' in Linux

In GDB:

disass main // Note here 'main' is a function // Similarly, it can be done for other functions.

Here are the steps to see/print the assembly code of any C program on your Windows:

In a console/terminal command prompt:

Write a C program in a C code editor like Code::Blocks and save it with filename extension .c

Compile and run it.

Once run successfully, go to the folder where you have installed your GCC compiler and enter the following command to get a ‘ .s ‘ file of the ‘ .c’ file

cd C:gcc gcc -S complete path of the C file ENTER

An example command (as in my case)

gcc -S D:Aa_C_Certifiedalternate_letters.c

This outputs a ‘.s’ file of the original ‘.c’ file.

After this, type the following command

cpp filename.s ENTER

Example command (as in my case)

cpp alternate_letters.s <enter>

This will print/output the entire assembly language code of your C program.

Use “-S” as an option. It displays the assembly output in the terminal.

gcc foo.c -masm=intel -fverbose-asm -O3 -S -o- |less.
-Son its own creates
foo.s. Jan 24, 2018 at 17:56

Thank you for reading this post How do you get assembler output from C/C++ source in GCC? at Tnhelearning.edu.vn You can comment, see more related articles below and hope to help you with interesting information.

Related Search:

Related Posts

Bernd Leno: Hành Trình Sự Nghiệp Của Thủ Môn Tài Năng
Bernd Leno: Hành Trình Sự Nghiệp Của Thủ Môn Tài Năng
Dominic Calvert-Lewin: Ngôi sao sáng giá của bóng đá Anh
Dominic Calvert-Lewin: Ngôi sao sáng giá của bóng đá Anh
Nguyễn Thị Oanh – Ngôi sao sáng của điền kinh Việt Nam
Nguyễn Thị Oanh – Ngôi sao sáng của điền kinh Việt Nam

Category: Top

Previous Post: « One continuous line drawing of young female scientist examine the virus that causes covid with laboratory microscope. Coronavirus vaccine research concept single line draw design vector illustration 3
Next Post: Bramty Juliette Net Worth, Age, TikTok, Height, Early Life, Bio, Career, Facts »

Copyright © 2025 · Tnhelearning.edu.vn - Useful Knowledge