web-dev-qa-db-fra.com

Comment afficher l'assembly derrière le code à l'aide de Visual C ++?

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?

105
user98188

Il y a plusieurs approches:

  1. 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).

  2. 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".

  3. 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.

140
inazaruk

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.

26
Vladimir Obrizan

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:


  • / Code d'assemblage FA; .asm
  • / FAc Code machine et assemblage; .la morue
  • / Code source et d'assemblage des FA; .asm
  • / FAcs Code machine, source et assembleur; .la morue
21
steve

Le moyen le plus simple est de lancer le débogueur et de vérifier la fenêtre de désassemblage.

9
diapir

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.

6
Peter Cordes

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.

4
jcopenha

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

4
Steve Steiner

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.

1
Dave L