Как получить вывод ассемблера из источника C / C ++ в gcc?

Как это сделать?

Если я хочу проанализировать, как что-то компилируется, как я могу получить испущенный ассемблерный код?

Используйте параметр -S для gcc (или g ++).

 gcc -S helloworld.c 

Это запустит препроцессор (cpp) поверх helloworld.c, выполнит начальную компиляцию, а затем остановится до запуска ассемблера.

По умолчанию будет helloworld.s файл helloworld.s . Выходной файл можно установить с помощью опции -o .

 gcc -S -o my_asm_output.s helloworld.c 

Конечно, это работает, только если у вас есть исходный источник. Альтернативой, если у вас есть только результирующий объектный файл, является использование objdump , установив параметр --disassemble (или -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 ++ из windows DOS на Win-XP, против подпрограммы, которая содержит неявный перевод

 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' 

Результатом является скомпилированный сгенерированный код, с которым начинается исходный код C ++ (код C ++ отображается как комментарии в сгенерированном streamе 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 $128,%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 $0,-16(%ebp) 

Используйте переключатель -S

 g++ -S main.cpp 

или также с gcc

 gcc -S main.c 

Также см. Это

Если то, что вы хотите видеть, зависит от компоновки вывода, тогда 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(){ if(/$ptr/o) { s/$ptr(\[[^\[\]]+\],$reg)/$2/o or s/($reg,)$ptr(\[[^\[\]]+\])/$1$3/o or s/$ptr/lc $1/oe; } if($prev =~ /\t(repz )?ret / and $_ =~ /\tnop |\txchg *ax,ax$/) { # drop this line } else { print $prev; $prev = $_; } } print $prev; close FH; в #!/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(){ if(/$ptr/o) { s/$ptr(\[[^\[\]]+\],$reg)/$2/o or s/($reg,)$ptr(\[[^\[\]]+\])/$1$3/o or s/$ptr/lc $1/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 для none, -O2 для агрессивной оптимизации).

В частности, в архитектуре RISC компилятор часто преобразует код, который почти не поддается распознаванию при оптимизации. Это впечатляет и увлекательно смотреть на результаты!

Ну, как сказали все, используйте -S вариант. Если вы используете параметр -save-temps, вы также можете получить предварительно обработанный файл ( .i), файл сборки ( .s) и файл объекта (*. O). (получить каждый из них с помощью -E, -S и -c.)

Используйте параметр -S:

 gcc -S program.c 

Как упоминалось ранее, посмотрите на флаг -S.

Также стоит посмотреть на семейство флагов ‘-fdump-tree’, в частности ‘-fdump-tree-all’, что позволяет увидеть некоторые из промежуточных форм gcc. Они часто могут быть более читабельными, чем ассемблер (по крайней мере, для меня), и позволяют увидеть, как выполняется прогон оптимизации.

Если вы ищете сборку LLVM:

 llvm-gcc -emit-llvm -S hello.c 

От: http://www.delorie.com/djgpp/v2faq/faq8_20.html

gcc -c -g -Wa, -a, -ad [другие параметры GCC] foo.c> foo.lst

в альтернативном ответе PhirePhly. Или просто используйте -S, как все сказали.

Я не вижу такой возможности среди ответов, вероятно, потому что вопрос с 2008 года, но в 2018 году вы можете использовать онлайн-сайт Мэтта Голдболта https://godbolt.org

Вы также можете локально git clone и запустить свой проект https://github.com/mattgodbolt/compiler-explorer

Выход этих комманд

Вот шаги, чтобы увидеть / распечатать код сборки любой программы на вашей Windows

консоль / терминал / командная строка:

  1. Напишите программу C в редакторе кода C, таком как кодовые блоки, и сохраните его с расширением .c

  2. Скомпилируйте и запустите его.

  3. После успешного запуска перейдите в папку, в которой вы установили свой компилятор gcc, и

    следующая команда для получения файла .s ‘файла .c’

    C: \ gcc> gcc -S полный путь файла C ENTER

    Пример команды (как в моем случае)

    C: \ gcc> gcc -SD: \ Aa_C_Certified \ alternate_letters.c

    Это выводит файл .s ‘исходного файла .c’

4. После этого введите следующую команду

C; \ gcc> cpp имя_файла.s ENTER

Пример команды (как в моем случае)

C; \ gcc> cpp alternate_letters.s

Это будет печатать / выводить весь код языка сборки вашей программы на языке C.

Используйте «-S» в качестве опции. Он отображает вывод сборки в терминале.

  • Почему медленная инструкция цикла? Не удалось ли Intel эффективно внедрить его?
  • Visual Studio 2010: ссылочные сборки Ориентация на версию с более высокой версией
  • Как загрузить сборку .NET для операций отражения и впоследствии выгрузить ее?
  • Динамически заменить содержимое метода C #?
  • Как загрузить сборку во время выполнения перед событием AssemblyResolve?
  • Почему mulss занимает всего 3 цикла на Хасуэлле, отличном от таблиц инструкций Агнера?
  • Возможно ли «декомпилировать» Windows .exe? Или, по крайней мере, рассмотреть Ассамблею?
  • Сколько циклов процессора требуется для каждой инструкции сборки?
  • Как определить, была ли assembly .NET построена для x86 или x64?
  • Инициализировать библиотеку при загрузке сборки
  • Примеры предварительной выборки?
  • Interesting Posts

    Как поймать Исключение из streamа

    Извлечение аккумулятора и запуск ноутбука в подключенном режиме?

    Создать консольное приложение .NET Core для вывода EXE?

    Как навсегда заблокировать KB4012218, KB4012219 и выпустить обновления?

    Что еще важнее CPU или ОЗУ для компиляции большого программного обеспечения, например, bootstrapping gcc?

    Почему Windows занимает больше дискового пространства по сравнению с Linux?

    RegisterStartupScript не работает с ScriptManager, Updatepanel. Почему это?

    Selenium “selenium.common.exceptions.NoSuchElementException” при использовании Chrome

    Почему OAuth v2 имеет доступ и токены обновления?

    Присоединение H264 * без * повторного кодирования

    F # Функции против значений

    Что такое «по умолчанию» реализация метода, определенного в интерфейсе?

    Android Recyclerview vs ListView с Viewholder

    Как отправить электронное письмо в .Net в соответствии с новыми политиками безопасности?

    При клонировании с помощью git bash в Windows происходит получение Fatal: UriFormatException

    Давайте будем гением компьютера.