Код сборки в С++
Я хотел бы узнать, как читается код сборки, сгенерированный компилятором. Где и как я могу оценить код сборки, сгенерированный на С++?
Спасибо
Ответы
Ответ 1
У вашего компилятора, вероятно, есть возможность генерировать вывод кода сборки, необязательно чередующийся с соответствующим исходным кодом. В Microsoft Visual С++ v10 это /Fa.
Или просто взгляните на двух бок о бок в своем отладчике.
Однако вы смотрите на это, не забудьте сравнить версии, построенные с оптимизацией и без нее. Удивительно видеть, сколько сегодня могут быть отброшены компиляторы, не влияя на работу программы.
Ответ 2
Из вашего объектного файла:
$ g++ -g -c -Wall yourfile.cpp -o yourfile.o
Тогда:
$ gdb yourfile.o
В GDB вы можете использовать команду disassemble
для просмотра сгенерированной сборки.
Итак, если ваш С++ источник:
int f() { return 1; }
Вы можете сделать в GDB:
(gdb) disassemble f
И выход будет:
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
Ответ 3
Если вы используете gcc, используйте аргумент -S, и выход компилятора не будет проходить через ассемблер.
Ответ 4
Для GCC и objdump.
Использование GCC для создания читаемой сборки?
Для Visual Studio, если вы используете среду IDE, вы можете изменить свойство "Выходные файлы" C/С++ в своих свойствах проекта и изменить "Ассемблерный вывод" на "Сборка с исходным кодом"
Это также флаг '/Fas' для компилятора Visual С++.
Ответ 5
//a.cpp
#include <iostream>
int main()
{
std::cout << "hello";
}
В gcc вы можете использовать опцию -S
, т.е. gcc -S a.cpp
генерирует 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