How can I view assembly code produced for C functions?
You may add the -S
tag to see the assembly code.
Like for a file TEST.c
, with gcc
, do,
gcc TEST.c -S
clang
also outputs the assembly code with a similar -S
tag.
After that just look for a file with a .S
extension.
How can I see the assembly code for a C++ program?
Ask the compiler
If you are building the program yourself, you can ask your compiler to emit assembly source. For most UNIX compilers use the -S
switch.
If you are using the GNU assembler, compiling with
-g -Wa,-alh
will give intermixed source and assembly on stdout (-Wa
asks compiler driver to pass options to assembler,-al
turns on assembly listing, and-ah
adds "high-level source" listing):g++ -g -c -Wa,-alh foo.cc
For Visual Studio, use
/FAsc
.
Peek into a binary
If you have a compiled binary,
- use
objdump -d a.out
on UNIX (also works for cygwin), dumpbin /DISASM foo.exe
on Windows.
Use your debugger
Debuggers could also show disassembly.
- Use
disas
command in GDB.
Useset disassembly-flavor intel
if you prefer Intel syntax. - or the disassembly window of Visual Studio on Windows.
How to view the assembly behind the code using Visual C++?
There are several approaches:
You can normally see assembly code while debugging C++ in visual studio (and eclipse too). For this in Visual Studio put a breakpoint on code in question and when debugger hits it rigth click and find "Go To Assembly" ( or press CTRL+ALT+D )
Second approach is to generate assembly listings while compiling. For this go to project settings -> C/C++ -> Output Files -> ASM List Location and fill in file name. Also select "Assembly Output" to "Assembly With Source Code".
Compile the program and use any third-party debugger. You can use OllyDbg or WinDbg for this. Also you can use IDA (interactive disassembler). But this is hardcore way of doing it.
How to view assembly code in codeblocks?
The compiler options:
-c # compile only (don't link)
-S # assemble only (don't compile or link)
-E # preprocess only (don't assemble, compile or link)
are mutually exclusive. Furthermore, you cannot specify:
-o foo.o # write output to `foo.o`
if you are specifying multiple input source files.
You are adding -S a43.c
to the Other compiler options. That means you
are adding them to the existing compilation options for your project. Those
options already include -c
by default, because that's the option to compile,
so adding -S
conflicts with -c
.
-S
does not take any argument, specifically no filename argument. It tellsgcc
only to assemble (not compile or link) the input files, whatever they are. So adding:
-S a43.c
as well as adding -S
to the existing options, adds an input file,a43.c
, to the project's compiler options. But of course Code::Blocks will add the
name of an input file to the compiler options whenever it compiles one of the
files in the project. So there will be two source filenames in the commandline.
Hence the error:
cannot specify -o with -c, -S or -E with multiple files
If you want to modify your Code::Blocks compilation options so that they will also
produce the assembly listing of each file compiled, then remove
-S a43.c
from Other compiler options and replace it with
-save-temps
Then, whenever gcc compiles a file foo.c
in the project, it will save the
intermediate files as:
foo.s # The assembly
foo.i # The preprocessed source
These files will be saved in the same directory as foo.c
itself; not in the
directory where the object file foo.o
is output.
See the documentation of -save-temps
in the GCC manual
Assembly Code from C program
If you compile your function as is, in optimization level3, -O3
the entire function is optimized out. This is because there is no return value and py
and ty
are anyways discarded after the function.
For reference the code is below
.globl decod
.def decod; .scl 2; .type 32; .endef
.seh_proc decod
decod:
.seh_endprologue
ret
.seh_endproc
If however, you add a return py;
at the end the code generated is as follows.
.globl decod
.def decod; .scl 2; .type 32; .endef
.seh_proc decod
decod:
.seh_endprologue
subl %r8d, %edx
movl %edx, %eax
imull %edx, %ecx
sall $31, %eax
sarl $31, %eax
xorl %ecx, %eax
ret
.seh_endproc
This is functionally identical to what you are expecting.
View Both Assembly and C code
You can run gdb in Text User Interface (TUI) mode:
gdb -tui <your-binary>
(gdb) b main
(gdb) r
(gdb) layout split
The layout split
command divides the window into two parts - one of them displaying the source code, the other one the corresponding assembly.
A few others tricks:
- set disassembly-flavor intel - if your prefer intel notation
- set print asm-demangle - demangles C++ names in assembly view
- ni - next instruction
- si - step instruction
If you do not want to use the TUI mode (e.g. your terminal does not like it), you can always do:
x /12i $pc
which means print 12 instructions from current program counter address - this also works with the tricks above (demangling, stepping instructions, etc.).
The "x /12i $pc" trick works in both gdb and cgdb, whereas "layout split" only works in gdb.
Enjoy :)
Related Topics
.C VS .Cc VS. .Cpp VS .Hpp VS .H VS .Cxx
Function Declaration Inside or Outside the Class
Launch Failed. Binary Not Found. Cdt on Eclipse Helios
Inheritance or Composition: Rely on "Is-A" and "Has-A"
Function Prologue and Epilogue in C
C++ Remove Punctuation from String
Concat Two 'Const Char' String Literals
C++ Expected Constant Expression
C++: Can Vector<Base> Contain Objects of Type Derived
What Is the Most Elegant Way to Read a Text File with C++
Allow for Range-Based for with Enum Classes
Is F(Void) Deprecated in Modern C and C++
(Partially) Specializing a Non-Type Template Parameter of Dependent Type
How to Use Covariant Return Types with Smart Pointers