¿Cómo se obtiene la salida del ensamblador del código fuente C / C++ en gcc?


¿Cómo se hace esto?

Si quiero analizar cómo se está compilando algo, ¿cómo obtendría el código ensamblador emitido?

Author: Ryan Tenney, 2008-09-26

14 answers

Utilice la opción -S para gcc (o g++).

gcc -S helloworld.c

Esto ejecutará el preprocesador (cpp) sobre helloworld.c, realice la compilación inicial y luego deténgase antes de que se ejecute el ensamblador.

De forma predeterminada, esto generará un archivo helloworld.s. El archivo de salida se puede configurar usando la opción -o.

gcc -S -o my_asm_output.s helloworld.c

Por supuesto, esto solo funciona si tiene la fuente original. Una alternativa si solo tiene el archivo objeto resultante es usar objdump, configurando la opción --disassemble (o -d para la forma abreviada).

objdump -S --disassemble helloworld > helloworld.dump

Esta opción funciona mejor si la opción de depuración está habilitada para el archivo objeto (-g en el momento de la compilación) y el archivo no se ha eliminado.

Ejecutar file helloworld le dará alguna indicación en cuanto al nivel de detalle que obtendrá al usar objdump.

 346
Author: Andrew Edgecombe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-01 01:33:38

Esto generará el asm con el código C + números de línea entrelazados para ver más fácilmente qué líneas generan qué código.

# 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

Encontrado en Algoritmos para programadores, página 4.

 154
Author: PhirePhly,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-26 02:51:05

La siguiente línea de comandos es de El blog de Christian Garbin

g++ -g -O -Wa,-aslh horton_ex2_05.cpp >list.txt

Ejecuté G++ desde una ventana de DOS en Win-XP, contra una rutina que contiene un cast implícito

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'

La salida es asssembled generated code iterspersed con el código C++ original (el código C++ se muestra como comentarios en el flujo asm generado)

  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)
 42
Author: Cr McDonough,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-01 01:08:07

Utilice el interruptor-S

g++ -S main.cpp

O también con ccg

gcc -S main.c

También ver esto

 21
Author: Doug T.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-26 00:11:06

Si lo que desea ver depende de la vinculación de la salida, entonces objdump en el archivo objeto de salida/ejecutable también puede ser útil además de la mencionada gcc-S. Aquí hay un script muy útil de Loren Merritt que convierte la sintaxis de objdump predeterminada en la sintaxis nasm más legible:

#!/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)/$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;

Sospecho que esto también se puede usar en la salida de gcc-S.

 12
Author: Dark Shikari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-26 00:14:23

Como todos han señalado, use la opción -S para GCC. También me gustaría añadir que los resultados pueden variar (salvajemente!) dependiendo de si agrega o no opciones de optimización (-O0 para ninguno, -O2 para optimización agresiva).

En arquitecturas RISC en particular, el compilador a menudo transformará el código casi más allá del reconocimiento al hacer optimización. ¡Es impresionante y fascinante ver los resultados!

 7
Author: Dan Lenski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-26 02:06:06

Bueno, como todos dijeron, use la opción-S. Si usa la opción-save-temps, también puede obtener el archivo preprocesado (.i), assembly file(.s) y archivo objeto (*.o). (obtenga cada uno de ellos usando -E,- S y-c.)

 7
Author: METADATA,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-13 08:56:37

Utilice la opción-S:

gcc -S program.c
 6
Author: Jeremy Ruten,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-26 00:11:32

Como se mencionó anteriormente, mire la bandera-S.

También vale la pena mirar la familia de banderas '-fdump-tree', en particular '-fdump-tree-all', que le permite ver algunas de las formas intermedias de gcc. Estos a menudo pueden ser más legibles que el ensamblador (al menos para mí), y le permiten ver cómo funcionan los pases de optimización.

 6
Author: Chris Jefferson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-11 16:31:10

Si está buscando el montaje LLVM:

llvm-gcc -emit-llvm -S hello.c
 6
Author: mcandre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-24 06:18:37

De: http://www.delorie.com/djgpp/v2faq/faq8_20.html

Gcc-c-g-Wa,-a,-ad [otras opciones de GCC] foo.c > foo.lst

En alternativa a la respuesta de PhirePhly O simplemente use -S como todos dijeron.

 4
Author: Anonymous,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-04 12:02:58

No veo esta posibilidad entre las respuestas, probablemente porque la pregunta es de 2008, pero en 2018 puedes usar el sitio web en línea de Matt Goldbolt https://godbolt.org

También puedes clonar localmente git y ejecutar su proyecto https://github.com/mattgodbolt/compiler-explorer

 4
Author: 421,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-24 15:27:12

La salida de estos comandos

Aquí están los pasos para ver/imprimir el código de ensamblado de cualquier programa C en su Windows

Consola / terminal / símbolo del sistema :

  1. Escriba un programa C en un editor de código C como codeblocks y guárdelo con una extensión .c

  2. Compilar y ejecutarlo.

  3. Una vez que se ejecute correctamente, vaya a la carpeta donde ha instalado su compilador gcc y proporcione el

    Siguiendo el comando para obtener un ' .s 'archivo de la' .c' file

    C:\ gcc> gcc-S ruta completa del archivo C ENTER

    Un comando de ejemplo (como en mi caso)

    C:\gcc> gcc-S D:\Aa_C_Certified\alternate_letters.c

    Esto produce a ' .s 'archivo del original'.c ' file

4 . Después de esto , escriba el siguiente comando

C;\gcc> nombre de archivo cpp.s ENTER

Ejemplo de comando (como en mi caso)

C;\gcc> cpp alternate_letters.s

Esto imprimirá / dará salida a todo el ensamblaje código de idioma de su programa C.

 2
Author: Ashutosh K Singh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-25 03:17:38

Utilice "-S" como opción. Muestra la salida del ensamblaje en el terminal.

 1
Author: Pizearke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-16 02:18:14