J'étais en train de lire une autre question concernant l'efficacité de deux lignes de code, et l'OP a déclaré qu'il avait regardé l'Assemblée derrière le code et que les deux lignes étaient identiques dans Assembly. Digression mise à part, comment puis-je voir le code d'assemblage créé lors de la compilation d'un programme.
J'utilise Visual C++ de Microsoft, mais j'aimerais également savoir s'il est possible d'afficher Assembly derrière du code écrit en Visual Basic.
Alors, comment puis-je voir le code Assembly derrière un programme écrit dans des langages de niveau supérieur tels que C++ et Visual Basic?
Il y a plusieurs approches:
Vous pouvez normalement voir le code Assembly lors du débogage de C++ dans Visual Studio (et Eclipse également). Pour cela, dans Visual Studio, placez un point d'arrêt sur le code en question et, lorsque le débogueur l'aura frappé, cliquez sur le bouton "Aller à l'assemblage" (ou appuyez sur CTRL + ALT + D).
La deuxième approche consiste à générer des listes d’assemblées lors de la compilation. Pour cela, allez dans les paramètres du projet -> C/C++ -> Fichiers de sortie -> ASM List Location et renseignez le nom du fichier. Sélectionnez également "Sortie d'assemblage" sur "Assemblage avec code source".
Compilez le programme et utilisez un débogueur tiers. Vous pouvez utiliser OllyDbg ou WinDbg pour cela. Vous pouvez aussi utiliser IDA (désassembleur interactif). Mais c’est une façon hardcore de le faire.
Remarque supplémentaire: il existe une grande différence entre la sortie de l'assembleur Debug et la première version. Le premier est utile pour apprendre comment le compilateur produit du code assembleur à partir de C++. La seconde est utile pour apprendre comment le compilateur optimise les différentes constructions C++. Dans ce cas, certaines transformations C++ - asm ne sont pas évidentes.
Spécifiez le commutateur/FA pour le compilateur cl. En fonction de la valeur du commutateur, seul le code d'assemblage ou le code de niveau supérieur et le code d'assemblage sont intégrés. Le nom de fichier obtient l'extension de fichier .asm. Voici les valeurs prises en charge:
Le moyen le plus simple est de lancer le débogueur et de vérifier la fenêtre de désassemblage.
La version précédente de cette réponse (un "hack" pour rextester.com) est généralement redondante maintenant que http://gcc.godbolt.org/ fournit CL 19 RC pour ARM, x86 et x86-64 (ciblant la convention d’appel de Windows, contrairement à gcc, clang et icc sur ce site).
L’explorateur du compilateur Godbolt est conçu pour formater correctement le compilateur asm en sortie, en supprimant le "bruit" des directives; optimisé loin).
Pendant un certain temps, CL était disponible sur http://gcc.beta.godbolt.org/ mais pas sur le site principal, mais à présent sur les deux.
Pour obtenir la sortie asv de MSVC à partir du http://rextester.com/l/cpp_online_compiler_visual compilateur en ligne: ajoutez /FAs
Aux options de la ligne de commande. Demandez à votre programme de trouver son propre chemin, calculez le chemin vers .asm
Et exportez-le. Ou exécutez un désassembleur sur le .exe
.
par exemple. http://rextester.com/OKI40941
#include <string>
#include <boost/filesystem.hpp>
#include <Windows.h>
using namespace std;
static string my_exe(void){
char buf[MAX_PATH];
DWORD tmp = GetModuleFileNameA( NULL, // self
buf, MAX_PATH);
return buf;
}
int main() {
string dircmd = "dir ";
boost::filesystem::path p( my_exe() );
//boost::filesystem::path dir = p.parent_path();
// transform c:\foo\bar\1234\a.exe
// into c:\foo\bar\1234\1234.asm
p.remove_filename();
system ( (dircmd + p.string()).c_str() );
auto subdir = p.end(); // pointing at one-past the end
subdir--; // pointing at the last directory name
p /= *subdir; // append the last dir name as a filename
p.replace_extension(".asm");
system ( (string("type ") + p.string()).c_str() );
// std::cout << "Hello, world!\n";
}
... code of functions you want to see the asm for goes here ...
type
est la version DOS de cat
. Je ne voulais pas inclure plus de code qui rendrait plus difficile la recherche des fonctions pour lesquelles je voulais voir l’asm. (Bien que l'utilisation de std :: string et de boost soit contraire à ces objectifs! Une manipulation de chaîne de style C qui fait davantage d'hypothèses sur la chaîne qu'il traite (et ignore la sécurité/allocation de longueur maximale en utilisant un gros tampon) sur le résultat de GetModuleFileNameA
serait beaucoup moins le code machine total.)
IDK pourquoi, mais cout << p.string() << endl
ne montre que le nom de base (c'est-à-dire le nom de fichier, sans les répertoires), même si l'impression de sa longueur indique qu'il ne s'agit pas simplement du nom. (Chromium48 sur Ubuntu 15.10). Il y a probablement un traitement anti-slash-escape à un moment donné dans cout
, ou entre la sortie standard du programme et le navigateur Web.
Dans Visual C++, les options du projet sous, Fichiers de sortie, je crois, propose une option pour la sortie de la liste ASM avec le code source. Ainsi, vous verrez le code source C/C++ et l'ASM résultant dans le même fichier.
Pour MSVC, vous pouvez utiliser l'éditeur de liens.
link.exe/dump/linumbers/disasm /out:foo.dis foo.dll
foo.pdb doit être disponible pour obtenir des symboles
Le réflecteur .NET de Red Gate est un outil génial qui m'a aidé plus d'une fois. Le côté positif de cet utilitaire, à part vous montrer facilement MSIL, est que vous pouvez analyser de nombreuses DLL tierces et que Reflector se charge de la conversion de MSIL en C # et VB.
Je ne promets pas que le code sera aussi clair que la source, mais vous ne devriez pas avoir beaucoup de difficulté à le suivre.