Код сборки в С++

Я хотел бы узнать, как читается код сборки, сгенерированный компилятором. Где и как я могу оценить код сборки, сгенерированный на С++?

Спасибо

Ответы

Ответ 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