¿Usar GCC para producir un ensamblaje legible?

Resuelto James asked hace 15 años • 11 respuestas

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

Estoy intentando reescribir un método C en ensamblaje y ver cómo lo hace GCC sería de gran ayuda.

James avatar Aug 18 '09 02:08 James
Aceptado

Si compila con símbolos de depuración (agregue -ga su línea de comando GCC, incluso si también está usando -O31 ), puede usarlo objdump -Spara producir un desensamblado más legible intercalado con la fuente C.

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

objdump -drwC -Minteles bueno:

  • -rmuestra nombres de símbolos en reubicaciones (como lo verá putsen las callinstrucciones a continuación)
  • -Rmuestra reubicaciones de enlaces dinámicos/nombres de símbolos (útil en bibliotecas compartidas)
  • -Cexige nombres de símbolos de C++
  • -wes el modo "ancho": no ajusta en línea los bytes del código de máquina
  • -Mintel: utilice una sintaxis similar a GAS/binutils MASM .intel_syntax noprefixen lugar de AT&T
  • -S: intercalar líneas fuente con desmontaje.

Podrías poner algo como alias disas="objdump -drwCS -Mintel"en tu ~/.bashrc. Si no está en x86, o si le gusta la sintaxis de AT&T, omita -Mintel.


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

Tenga en cuenta que esto no se utiliza -r, por lo que call rel32=-4no está anotado con el putsnombre del símbolo. Y parece un roto callque salta al medio de la instrucción de llamada en principal. Recuerde que el rel32desplazamiento en la codificación de la llamada es solo un marcador de posición hasta que el vinculador complete un desplazamiento real (a un código auxiliar PLT en este caso, a menos que vincule estáticamente libc).


Nota al pie 1 : El entrelazado de fuentes puede resultar complicado y no muy útil en compilaciones optimizadas; para eso, considere https://godbolt.org/ u otras formas de visualizar qué instrucciones van con qué líneas fuente. En el código optimizado no siempre hay una única línea fuente que representa una instrucción , pero la información de depuración seleccionará una línea fuente para cada instrucción ASM.

Bastien Léonard avatar Aug 17 '2009 19:08 Bastien Léonard

Si le das a GCC la bandera -fverbose-asm, lo hará.

Coloque información de comentarios adicional en el código ensamblador generado para hacerlo más legible.

[...] Los comentarios agregados incluyen:

  • información sobre la versión del compilador y las opciones de la línea de comandos,
  • las líneas de código fuente asociadas con las instrucciones de ensamblaje, en el formato NOMBRE DE ARCHIVO: NÚMERO DE LÍNEA: CONTENIDO DE LA LÍNEA,
  • sugerencias sobre qué expresiones de alto nivel corresponden a los distintos operandos de instrucciones ensambladoras.
Kasper avatar Aug 17 '2009 20:08 Kasper

Utilice el interruptor -S (nota: S mayúscula) a GCC y emitirá el código ensamblador a un archivo con una extensión .s. Por ejemplo, el siguiente comando:

gcc -O2 -S foo.c

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

Extraído directamente de http://www.delorie.com/djgpp/v2faq/faq8_20.html (pero eliminando errores -c)

Andrew Keeton avatar Aug 17 '2009 19:08 Andrew Keeton