2010-04-09 15 views
32

Estoy considerando adquirir una comprensión muy rudimentaria del ensamblaje. Mi objetivo actual es simple: comprensión MUY BÁSICA de la salida del ensamblador GCC al compilar C/C++ con el modificador -S para x86/x86-64.Aprendiendo a leer la salida del ensamblador GCC

Solo lo suficiente para hacer cosas simples como mirar una sola función y verificar si GCC optimiza cosas que espero que desaparezcan.

¿Alguien tiene/sabe de una introducción al montaje verdaderamente concisa, relevante para GCC y específicamente con el propósito de leer, y una lista de las instrucciones más importantes que cualquier persona que lea casualmente el ensamblaje debe saber?

+0

No ha especificado qué idioma de ensamblaje de destino le interesa. Intel x86? PowerPC? –

+0

Gracias, lo añadí. – porgarmingduod

Respuesta

19

Si está utilizando gcc o sonido metálico, el -masm = argumento de Intel le dice al compilador que genere el montaje con la sintaxis de Intel en lugar de en & sintaxis T, y el argumento --save-temps le dice al compilador para guardar archivos temporales (origen preprocesado, resultado de ensamblaje, archivo de objeto no enlazado) en el directorio desde el que se llama a GCC.

Obtener una comprensión superficial del ensamblaje x86 debería ser fácil con todos los recursos disponibles. Aquí hay uno de esos recursos: http://www.cs.virginia.edu/~evans/cs216/guides/x86.html.

También puede usar disasm y gdb para ver qué está haciendo un programa compilado.

+1

Ese artículo es una lectura corta y agradable, gracias. – porgarmingduod

+3

Si realiza el desensamblaje de GDB, también puede usar 'set disassembly-flavor intel' para la sintaxis de Intel. –

0

Estoy seguro de que hay libros introductorios y sitios web, pero una forma bastante eficiente de aprenderlo es obtener las referencias de Intel y luego intentar hacer cosas simples (como matemática entera y lógica booleana) en su idioma favorito de alto nivel y luego mira cuál es el código binario resultante.

+0

Es un poco complicado para GCC usar la sintaxis de AT & T para su salida. 'MOV' no solo se llama' MOV', y el orden de los operandos no siempre será el que figura en los manuales de Intel. –

+2

Si está compilando para x86, puede usar el indicador del compilador -masm = intel para obtener gcc en el ensamblaje de salida que se parece más a los manuales de Intel. – nategoose

2

"casualmente leyendo asamblea" lol (muy bien)

Me gustaría empezar por el siguiente en GDB en tiempo de ejecución; obtienes una mejor idea de lo que está sucediendo. Pero entonces tal vez sea solo yo. Desmontará una función para usted (disass func) y luego puede pasar por ella

Si está haciendo esto únicamente para verificar las optimizaciones, no se preocupe.

a) el compilador hace un buen trabajo

b) que no será capaz de entender lo que está haciendo de todos modos (nadie puede)

+5

A veces encuentro que el código optimizado es más fácil de leer porque detecta dónde está siendo redundante y lo cambia a algo similar a lo que escribiría. – avpx

+4

Para mí, sé que es una buena idea hacer esto únicamente para verificar las optimizaciones. La razón es que cada vez que veo al compilador haciendo algo inteligente sobre * situación X *, no pasaré ningún momento en el futuro * preguntándome *. avpx también tiene un muy buen punto. – porgarmingduod

+1

+1, esa es una gran idea, he agregado 'disass func' a un CW en gdb: http://stackoverflow.com/questions/2588853/the-community-driven-gdb-primer/2611474#2611474. Por supuesto, siéntete libre de editar lo que he puesto allí. –

1

A diferencia de lenguajes de alto nivel, no hay realmente no mucho (si lo hay) diferencia entre poder leer el ensamblaje y poder escribirlo. Las instrucciones tienen una relación de uno a uno con los códigos de operación de la CPU: no hay complejidad para omitir y al mismo tiempo conservar la comprensión de lo que hace la línea de código. (No es como un lenguaje de nivel superior donde puede ver una línea que dice "print $ var" y no necesita saber o preocuparse por cómo se publica en la pantalla.)

Si aún desea aprender ensamblaje, pruebe el libro Assembly Language Step-by-Step: Programming with Linux, por Jeff Duntemann.

+0

No estoy de acuerdo (pero no renunciaría por ese motivo); es mucho más fácil entender algo que está delante de ti que se sabe que está bien formado y crear tú mismo ese código bien formado. Poder leer el ensamblaje ciertamente puede ayudar/editar/ensamblar, pero poder leerlo está muy lejos de ser capaz de crear incluso una funcionalidad trivial desde cero. Es posible que pueda comprender cuando las personas me hablan en los idiomas que he estudiado, ¡pero estoy seguro de que no puedo hablar ninguno de ellos de formas bien formadas! –

3

Normalmente busco la documentación del procesador cuando me enfrento a un nuevo dispositivo, y luego solo busco los códigos de operación cuando encuentro unos que no conozco.

En Intel, afortunadamente los códigos de operación son bastante sensatos. PowerPC no tanto en mi opinión. MIPS fue mi favorito. Para MIPS, tomé prestado el pequeño libro de referencia de mi vecino, y para PPC, tenía documentación de IBM en un PDF que era útil para buscar. (Y para Intel, creo que en su mayoría y luego ver los registros para asegurarse de que estoy acertando! Heh)

Básicamente, el montaje en sí es fácil. Básicamente, hace tres cosas: mover datos entre la memoria y los registros, operar los datos en los registros y cambiar el contador del programa. El mapeo entre el idioma de su elección y el ensamblado requerirá cierto estudio (por ejemplo, aprender cómo reconocer una llamada de función virtual), y para esto una vista "integrada" de fuente y desensamblaje (como se puede obtener en Visual Studio) es muy útil.

+0

x86 ... ¿sensato? Esa es una nueva – jalf

21

Debe utilizar la opción -fverbose-asm de GCC. Hace que el compilador genere información adicional (en forma de comentarios) que facilita la comprensión de la relación del código ensamblador con el código C/C++ original.

+0

Es bueno saberlo, gracias. – porgarmingduod

Cuestiones relacionadas