Как вы получаете вывод ассемблера из источника C/C++ в gcc?
Как это делается?
Если я хочу проанализировать, как что-то компилируется, как бы я получил излучаемый код сборки?
14 ответов
использовать -S
опция для gcc (или g++).
gcc -S helloworld.c
это запустит препроцессор (cpp) над helloworld.c, выполните начальную компиляцию, а затем остановитесь перед запуском ассемблера.
по умолчанию это выведет файл helloworld.s
. Выходной файл можно по-прежнему установить с помощью .
gcc -S -o my_asm_output.s helloworld.c
конечно, это работает только в том случае, если у вас есть исходный источник.
Альтернативой, если у вас есть только результирующий объектный файл, является использование objdump
, установив (или -d
для сокращенной форме).
objdump -S --disassemble helloworld > helloworld.dump
эта опция работает лучше всего, если опция отладки включена для объектного файла (-g
во время компиляции), и файл не был удален.
под управлением file helloworld
даст вам некоторое представление об уровне детализации, который вы получите с помощью objdump.
это создаст asm с кодом C + номерами строк, переплетенными, чтобы легче увидеть, какие строки генерируют какой код.
# create assembler code:
c++ -S -fverbose-asm -g -O2 test.cc -o test.s
# create asm interlaced with source lines:
as -alhnd test.s > test.lst
нашли в алгоритмы для программистов, стр. 4.
следующая командная строка из блог Кристиана Гарбена
g++ -g -O -Wa,-aslh horton_ex2_05.cpp >list.txt
я запустил G++ из окна DOS на Win-XP против подпрограммы, которая содержит неявный cast
c:\gpp_code>g++ -g -O -Wa,-aslh horton_ex2_05.cpp >list.txt
horton_ex2_05.cpp: In function `int main()':
horton_ex2_05.cpp:92: warning: assignment to `int' from `double'
вывод-это asssembled сгенерированный код iterspersed с исходным кодом C++ (код c++ показан как комментарии в сгенерированном потоке asm)
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 8,%esp
?GAS LISTING C:\DOCUME~1\CRAIGM~1\LOCALS~1\Temp\ccx52rCc.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 ,-16(%ebp)
Если то, что вы хотите увидеть, зависит от связывания вывода, то objdump в выходном объектном файле / исполняемом файле также может быть полезен в дополнение к вышеупомянутому gcc-S. Вот очень полезный скрипт Loren Merritt, который преобразует синтаксис objdump по умолчанию в более читаемый синтаксис nasm:
#!/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)//o or
s/($reg,)$ptr(\[[^\[\]]+\])//o or
s/$ptr/lc /oe;
}
if($prev =~ /\t(repz )?ret / and
$_ =~ /\tnop |\txchg *ax,ax$/) {
# drop this line
} else {
print $prev;
$prev = $_;
}
}
print $prev;
close FH;
Я подозреваю, что это также может быть использовано на выходе gcc-S.
как все отметили, используйте -S
опция для GCC. Я также хотел бы добавить, что результаты могут отличаться (дико!) в зависимости от того, добавляете ли вы параметры оптимизации (-O0
нет, -O2
для агрессивной оптимизации).
на архитектурах RISC, в частности, компилятор часто преобразует код почти до неузнаваемости при оптимизации. Это впечатляет и завораживает, чтобы посмотреть на результаты!
Ну, как все сказали, используйте-s вариант. Если вы используете опцию-save-temps, вы также можете получить предварительно обработанный файл (.я), файл сборки(.S) и объектный файл(*.о.) (получите каждый из них, используя -E, - S и-c.)
Как упоминалось ранее, посмотрите на флаг-s.
также стоит посмотреть на семейство флагов "- fdump-tree", в частности "-fdump-tree-all", которое позволяет увидеть некоторые промежуточные формы gcc. Они часто могут быть более читаемыми, чем ассемблер (по крайней мере, для меня), и позволяют увидеть, как выполняется оптимизация.
From:http://www.delorie.com/djgpp/v2faq/faq8_20.html
gcc-c-g-Wa,-a, - ad [другие параметры GCC] foo.c > foo.lst
в альтернативе ответу Фирепли Или просто использовать-S, как все говорили.
Я не вижу этой возможности среди ответов, вероятно, потому, что вопрос с 2008 года, но в 2018 году вы можете использовать онлайн-сайт Мэтта Голдболта https://godbolt.org
вы также можете локально клонировать git и запускать его проектhttps://github.com/mattgodbolt/compiler-explorer
вот шаги, чтобы увидеть / распечатать код сборки любой программы C на вашем Windows
консоль /терминал/ командную строку :
напишите программу C в редакторе кода C, например codeblocks, и сохраните ее с расширением .c
скомпилируйте и запустите его.
-
после успешного запуска перейдите в папку, в которой вы установили компилятор gcc, и дайте
следующая команда, чтобы получить'.s 'файл'.c ' file
C:\ gcc> GCC-s полный путь к файлу C введите
пример команды ( как в моем случае)
C:\gcc> gcc-S D:\Aa_C_Certified\alternate_letters - ... c
это выводит a ' .файл s' оригинала ' .c ' file
4 . После этого введите следующую команду
C;\gcc> имя файла cpp.s введите
пример команды ( как в моем случае)
C;\gcc> cpp alternate_letters.s
Это будет печатать / выводить весь код языка сборки вашей программы C.