Estaba leyendo otra pregunta relacionada con la eficiencia de dos líneas de código, y el OP dijo que miró el ensamblaje detrás del código y que ambas líneas eran idénticas en ensamblaje. Aparte de la digresión, ¿cómo podría ver el código ensamblador creado cuando se compila un programa?
Estoy usando Visual C ++ de Microsoft, pero también me gustaría saber si es posible ver el ensamblaje detrás del código escrito en Visual Basic.
Entonces, ¿cómo veo el código ensamblador detrás de un programa escrito en lenguajes de nivel superior como C ++ y Visual Basic?
visual-c++
assembly
Bart
fuente
fuente
Respuestas:
Hay varios enfoques:
Normalmente puede ver el código ensamblador mientras depura C ++ en Visual Studio (y también eclipse). Para esto, en Visual Studio, ponga un punto de interrupción en el código en cuestión y cuando el depurador lo golpee, haga clic derecho y busque "Ir al ensamblaje" (o presione CTRL + ALT + D)
El segundo enfoque consiste en generar listas de ensamblado durante la compilación. Para esto, vaya a la configuración del proyecto -> C / C ++ -> Archivos de salida -> Ubicación de la lista ASM y complete el nombre del archivo. También seleccione "Salida de ensamblado" a "Ensamblado con código fuente".
Compile el programa y use cualquier depurador de terceros. Puede usar OllyDbg o WinDbg para esto. También puede utilizar IDA (desensamblador interactivo). Pero esta es una forma incondicional de hacerlo.
fuente
Nota adicional: existe una gran diferencia entre la salida del ensamblador de depuración y la versión uno. El primero es bueno para aprender cómo el compilador produce código ensamblador a partir de C ++. El segundo es bueno para aprender cómo el compilador optimiza varias construcciones de C ++. En este caso, algunas transformaciones de C ++ a conjunto no son obvias.
fuente
Especifique el modificador / FA para el compilador cl. Dependiendo del valor del interruptor, solo se integra el código de ensamblaje o el código de alto nivel y el código de ensamblaje. El nombre de archivo obtiene la extensión de archivo .asm. Estos son los valores admitidos:
fuente
La forma más sencilla es activar el depurador y comprobar la ventana de desmontaje .
fuente
La versión anterior de esta respuesta (un "truco" para rextester.com) es mayormente redundante ahora que http://gcc.godbolt.org/ proporciona CL 19 RC para ARM, x86 y x86-64 (dirigido a la convención de llamadas de Windows , a diferencia de gcc, clang y icc en ese sitio).
El explorador de compiladores de Godbolt está diseñado para formatear muy bien la salida de asm del compilador, eliminando el "ruido" de las directivas, por lo que recomiendo encarecidamente usarlo para buscar en asm funciones simples que toman argumentos y devuelven un valor (para que no sean optimizado).
Durante un tiempo, CL estuvo disponible en http://gcc.beta.godbolt.org/ pero no en el sitio principal, pero ahora está en ambos.
Para obtener la salida MSVC asm del compilador en línea http://rextester.com/l/cpp_online_compiler_visual : Agregue
/FAs
las opciones de la línea de comandos. Haga que su programa encuentre su propia ruta y calcule la ruta al.asm
y lo descargue. O ejecute un desensamblador en el.exe
.por ejemplo, http://rextester.com/OKI40941
type
es la versión DOS decat
. No quería incluir más código que dificultaría la búsqueda de las funciones para las que quería ver el asm. (¡Aunque usa std :: string y boost run en contra de esos objetivos! Alguna manipulación de cadena de estilo C que hace más suposiciones sobre la cadena que está procesando (e ignora la seguridad / asignación de longitud máxima mediante el uso de un búfer grande) en el resultado deGetModuleFileNameA
would ser mucho menos código de máquina total).IDK por qué, pero
cout << p.string() << endl
solo muestra el nombre base (es decir, el nombre del archivo, sin los directorios), aunque imprimir su longitud muestra que no es solo el nombre simple. (Chromium48 en Ubuntu 15.10). Probablemente haya algún procesamiento de escape de barra invertida en algún momentocout
o entre la salida estándar del programa y el navegador web.fuente
.c_str()
imprime lo que parece un puntero. Si sigue el enlace, verá el código para hexdump astd::string
(desactivado con#if 0
). Resulta que la cadena está bien, perocout
no llega al navegador web. Tampoco hay caracteres que no sean ascii, solo barras invertidas.subdir--; p /= *subdir;
¿no redujo p al nombre del archivo? O tal vez no entiendo bien lo que está intentando imprimir.subdir--
seguido dep /= *subdir
cuándosubdir
fue originalmentep.end()
GetModuleFileNameA
estaba regresandoa.exe
. No fue hasta que lo descargué e imprimí la longitud que sabía que estaba funcionando, y podía hacer que el programa manipulara la ruta, simplemente no podía imprimir la ruta\\r
(bueno,\r
cuando el compilador lo genera) parte del nombre de archivo que se tradujo mal al renderizar para el navegador web. El usop.generic_string()
funciona, pero las barras invertidas son barras inclinadas hacia adelante.En Visual C ++, las opciones del proyecto en Archivos de salida creo que tienen una opción para generar la lista de ASM con el código fuente. Entonces verá el código fuente de C / C ++ y el ASM resultante, todos en el mismo archivo.
fuente
Para MSVC puede utilizar el vinculador.
link.exe / dump / linenumbers / disaster /out:foo.dis foo.dll
foo.pdb debe estar disponible para obtener símbolos
fuente
.NET Reflector de Red Gate es una herramienta bastante impresionante que me ha ayudado más de un par de veces. El lado positivo de esta utilidad fuera de mostrarte fácilmente MSIL es que puedes analizar muchas DLL de terceros y hacer que Reflector se encargue de convertir MSIL a C # y VB.
No prometo que el código sea tan claro como la fuente, pero no debería tener muchos problemas para seguirlo.
fuente
Si está hablando de depurar para ver el código ensamblador, la forma más fácil es Debug-> Windows-> Disassembly (o Alt-8). Esto le permitirá ingresar a una función llamada y permanecer en Desmontaje.
fuente