I would like to learn reading the assembly code generated by the compiler. Where and how coul开发者_Go百科d I assess the assembly code generated from C++ ?
Thanks
Your compiler likely has an option to generate assembly code output, optionally interleaved with the corresponding source code. In Microsoft Visual C++ v10 this is /Fa.
Or, just look at the two side-by-side in your debugger.
However you look at this, be sure to compare the versions built with and without optimization. It's amazing to see how much can be discarded by today's compilers without affecting the operation of the program.
If you are using gcc, use the -S argument and the compiler's output won't go through the assembler.
From your object file:
$ g++ -g -c -Wall yourfile.cpp -o yourfile.o
Then:
$ gdb yourfile.o
Once in GDB you could use disassemble
command to view the generated assembly.
So, if your C++ source is:
int f() { return 1; }
You can do in GDB:
(gdb) disassemble f
And the output will be:
Dump of assembler code for function f:
0x00000000 <f+0>: push %ebp
0x00000001 <f+1>: mov %esp,%ebp
0x00000003 <f+3>: mov $0x1,%eax
0x00000008 <f+8>: pop %ebp
0x00000009 <f+9>: ret
For GCC and objdump. Using GCC to produce readable assembly?
For Visual Studio, if you are using the IDE, you can modify the C/C++ 'Output Files' property in your project's properties, and change 'Assembler Output' to 'Assembly with Source Code'
This is also the '/Fas' flag for Visual C++ compiler.
//a.cpp
#include <iostream>
int main()
{
std::cout << "hello";
}
On gcc you can use the -S
option, i.e gcc -S a.cpp
generates a.s
(a.s):
.file "a.cpp"
.lcomm __ZStL8__ioinit,1,1
.def ___main; .scl 2; .type 32; .endef
.section .rdata,"dr"
LC0:
.ascii "hello\0"
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $16, %esp
call ___main
movl $LC0, 4(%esp)
movl $__ZSt4cout, (%esp)
call __ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
movl $0, %eax
leave
ret
.def ___tcf_0; .scl 3; .type 32; .endef
___tcf_0:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl $__ZStL8__ioinit, (%esp)
call __ZNSt8ios_base4InitD1Ev
leave
ret
.def __Z41__static_initialization_and_destruction_0ii; .scl
3; .type 32; .endef
__Z41__static_initialization_and_destruction_0ii:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
cmpl $1, 8(%ebp)
jne L3
cmpl $65535, 12(%ebp)
jne L3
movl $__ZStL8__ioinit, (%esp)
call __ZNSt8ios_base4InitC1Ev
movl $___tcf_0, (%esp)
call _atexit
L3:
leave
ret
.def __GLOBAL__I_main; .scl 3; .type 32; .endef
__GLOBAL__I_main:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl $65535, 4(%esp)
movl $1, (%esp)
call __Z41__static_initialization_and_destruction_0ii
leave
ret
.section .ctors,"w"
.align 4
.long __GLOBAL__I_main
.def __ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc;
.scl 2; .type 32; .endef
.def __ZNSt8ios_base4InitD1Ev; .scl 2; .type 32;
.endef
.def __ZNSt8ios_base4InitC1Ev; .scl 2; .type 32;
.endef
.def _atexit; .scl 2; .type 32; .endef
精彩评论