code assembler asm c gcc assembly

assembler - ¿Usando GCC para producir ensamblajes legibles?



use assembler in c (9)

Me preguntaba cómo usar GCC en mi archivo fuente C para volcar una versión mnemotécnica del código de la máquina para poder ver en qué se estaba compilando mi código. Puedes hacer esto con Java, pero no he podido encontrar una manera con GCC.

Estoy tratando de volver a escribir un método C en ensamblado y ver cómo GCC lo hace sería una gran ayuda.


Use el conmutador -S (nota: mayúscula S) a GCC, y emitirá el código de ensamblaje a un archivo con la extensión .s. Por ejemplo, el siguiente comando:

gcc -O2 -S foo.c

dejará el código de ensamblaje generado en el archivo foo.s.

Arrancado directamente desde http://www.delorie.com/djgpp/v2faq/faq8_20.html (pero eliminando el error -c )


¿ gcc -S -fverbose-asm -O source.c luego gcc -S -fverbose-asm -O source.c en el archivo ensamblador de source.s generado?

El código del ensamblador generado va a source.s (puede anularlo con -o assembler-filename ); La opción -fverbose-asm le pide al compilador que emita algunos comentarios del ensamblador "explicando" el código del ensamblador generado. La opción -O le pide al compilador que optimice un poco (podría optimizar más con -O2 o -O2 ).

Si quieres entender qué está haciendo gcc intenta pasar -fdump-tree-all pero ten cuidado: obtendrás cientos de archivos de volcado.

Por cierto, GCC es extensible a través de complementos o con MELT (un lenguaje de alto nivel específico del dominio para extender GCC).


El uso del conmutador -S a GCC en sistemas basados ​​en x86 produce un volcado de la sintaxis de AT&T, de forma predeterminada, que se puede especificar con el -masm=att , así:

gcc -S -masm=att code.c

Mientras que si deseas producir un volcado en la sintaxis de Intel, puedes usar el -masm=intel , así:

gcc -S -masm=intel code.c

(Ambos producen volcados de code.c en su sintaxis, en el archivo code.s respectivamente)

Para producir efectos similares con objdump, querría usar el --disassembler-options= intel / att , un ejemplo (con volcados de código para ilustrar las diferencias en la sintaxis):

$ objdump -d --disassembler-options=att code.c

080483c4 <main>: 80483c4: 8d 4c 24 04 lea 0x4(%esp),%ecx 80483c8: 83 e4 f0 and $0xfffffff0,%esp 80483cb: ff 71 fc pushl -0x4(%ecx) 80483ce: 55 push %ebp 80483cf: 89 e5 mov %esp,%ebp 80483d1: 51 push %ecx 80483d2: 83 ec 04 sub $0x4,%esp 80483d5: c7 04 24 b0 84 04 08 movl $0x80484b0,(%esp) 80483dc: e8 13 ff ff ff call 80482f4 <puts@plt> 80483e1: b8 00 00 00 00 mov $0x0,%eax 80483e6: 83 c4 04 add $0x4,%esp 80483e9: 59 pop %ecx 80483ea: 5d pop %ebp 80483eb: 8d 61 fc lea -0x4(%ecx),%esp 80483ee: c3 ret 80483ef: 90 nop

y

$ objdump -d --disassembler-options=intel code.c

080483c4 <main>: 80483c4: 8d 4c 24 04 lea ecx,[esp+0x4] 80483c8: 83 e4 f0 and esp,0xfffffff0 80483cb: ff 71 fc push DWORD PTR [ecx-0x4] 80483ce: 55 push ebp 80483cf: 89 e5 mov ebp,esp 80483d1: 51 push ecx 80483d2: 83 ec 04 sub esp,0x4 80483d5: c7 04 24 b0 84 04 08 mov DWORD PTR [esp],0x80484b0 80483dc: e8 13 ff ff ff call 80482f4 <puts@plt> 80483e1: b8 00 00 00 00 mov eax,0x0 80483e6: 83 c4 04 add esp,0x4 80483e9: 59 pop ecx 80483ea: 5d pop ebp 80483eb: 8d 61 fc lea esp,[ecx-0x4] 80483ee: c3 ret 80483ef: 90 nop


Me gustaría agregar a estas respuestas que si le da a gcc la -fverbose-asm , el ensamblador que emite será mucho más claro de leer.


No le he dado una inyección a gcc, pero en caso de g ++. El siguiente comando funciona para mí. -g para la compilación de depuración y -Wa, -adhln se pasa al ensamblador para su listado con código fuente

g ++ -g -Wa, -adhln src.cpp


Puedes usar gdb para esto como objdump.

Este extracto se toma de http://sources.redhat.com/gdb/current/onlinedocs/gdb_9.html#SEC64

Aquí hay un ejemplo que muestra una fuente mixta + ensamblaje para Intel x86:

(gdb) disas /m main Dump of assembler code for function main: 5 { 0x08048330 : push %ebp 0x08048331 : mov %esp,%ebp 0x08048333 : sub $0x8,%esp 0x08048336 : and $0xfffffff0,%esp 0x08048339 : sub $0x10,%esp 6 printf ("Hello./n"); 0x0804833c : movl $0x8048440,(%esp) 0x08048343 : call 0x8048284 7 return 0; 8 } 0x08048348 : mov $0x0,%eax 0x0804834d : leave 0x0804834e : ret End of assembler dump.


Use el conmutador -S (nota: mayúscula S) a GCC, y emitirá el código de ensamblaje a un archivo con la extensión .s. Por ejemplo, el siguiente comando:

gcc -O2 -S -c foo.c


gcc.godbolt.org es una herramienta muy útil, ya que solo tienen compiladores de C ++, pero puedes usar el indicador -xc para tratar el código como C. Luego generará una lista de ensamblados para tu código en paralelo y puedes usar Colourise Opción para generar barras de colores para indicar visualmente qué código fuente se asigna al ensamblaje generado. Por ejemplo el siguiente código:

#include <stdio.h> void func() { printf( "hello world/n" ) ; }

usando la siguiente línea de comando:

-x c -std=c99 -O3

y Colourise generaría lo siguiente:


Si compila con símbolos de depuración, puede usar objdump para producir un desensamblaje más legible.

>objdump --help [...] -S, --source Intermix source code with disassembly -l, --line-numbers Include line numbers and filenames in output

objdump -drwC -Mintel es bueno:

  • -r muestra los nombres de los símbolos en las reubicaciones (para que vea las instrucciones de call continuación)
  • -R muestra relocalizaciones de enlaces dinámicos / nombres de símbolos (útiles en bibliotecas compartidas)
  • -C desmangle los nombres de los símbolos de C ++
  • -w es el modo "ancho": no envuelve los bytes del código de la máquina
  • -Mintel : use la sintaxis de .intel_syntax noprefix GAS / binutils tipo MASM .intel_syntax noprefix lugar de AT&T
  • -S : entrelazar lineas fuente con desmontaje.

Puedes poner algo como alias disas="objdump -drwCS -Mintel" en tu ~/.bashrc

Ejemplo:

> gcc -g -c test.c > objdump -d -M intel -S test.o test.o: file format elf32-i386 Disassembly of section .text: 00000000 <main>: #include <stdio.h> int main(void) { 0: 55 push ebp 1: 89 e5 mov ebp,esp 3: 83 e4 f0 and esp,0xfffffff0 6: 83 ec 10 sub esp,0x10 puts("test"); 9: c7 04 24 00 00 00 00 mov DWORD PTR [esp],0x0 10: e8 fc ff ff ff call 11 <main+0x11> return 0; 15: b8 00 00 00 00 mov eax,0x0 } 1a: c9 leave 1b: c3 ret