Utiliser GCC pour produire un assemblage lisible?

je me demandais comment utiliser GCC sur mon fichier C source pour Dumper une version mnémotechnique du code machine afin que je puisse voir dans quoi mon code était compilé. Vous pouvez le faire avec Java, mais je n'ai pas réussi à trouver un moyen avec GCC.

j'essaie de réécrire une méthode C en assemblage et voir comment le GCC fait serait une grande aide.

211
demandé sur Ryan Tenney 2009-08-17 23:22:17

9 réponses

si vous compilez avec les symboles de débogage, vous pouvez utiliser objdump pour produire un désassemblage plus lisible.

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

objdump -drwC -Mintel est gentil:

  • -r affiche les noms des symboles sur les réinstallations (donc vous verriez puts dans l'instruction call ci-dessous)
  • -R montre des transferts de liens dynamiques / noms de symboles (utiles sur les bibliothèques partagées)
  • -C démangles c++ symbol names
  • -w est le mode" wide": il n'enroule pas les octets de code machine
  • -Mintel : utiliser des gaz/binutils de type MASM .intel_syntax noprefix syntaxe au lieu de AT &T
  • -S : interleave les lignes de source avec le démontage.

vous pourriez mettre quelque chose comme alias disas="objdump -drwCS -Mintel" dans votre ~/.bashrc


exemple:

> 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
284
répondu Bastien Léonard 2018-06-02 01:20:13

je voudrais ajouter à ces réponses que si vous donnez de gcc le drapeau -fverbose-asm , l'assembleur, il émet sera beaucoup plus clair à lire.

86
répondu kmm 2013-04-30 22:42:37

utilisez le commutateur-s (note: capital s) vers GCC, et il émettra le code d'assemblage vers un fichier avec A.s d'extension. Par exemple, la commande suivante:

gcc -O2 -S foo.c

laissera le code d'assemblage généré sur le fichier foo.S.

Ripped straight from http://www.delorie.com/djgpp/v2faq/faq8_20.html (mais suppression de -c erroné)

69
répondu Andrew Keeton 2016-05-18 21:26:44

utilisant le commutateur -S vers GCC sur les systèmes basés sur x86 produit un dump de syntaxe AT&T, par défaut, qui peut être spécifié avec le commutateur -masm=att , comme suit:

gcc -S -masm=att code.c

alors que si vous souhaitez produire un dump en syntaxe Intel, vous pouvez utiliser le commutateur -masm=intel , comme suit:

gcc -S -masm=intel code.c

(les deux produisent des dumps de code.c dans leur syntaxe diverse, dans le fichier code.s respectivement)

afin de produire des effets similaires avec objdump, vous souhaitez utiliser le --disassembler-options= intel / att switch, un exemple (avec code dumps pour illustrer les différences de syntaxe):

 $ objdump -d --disassembler-options=att code.c
 080483c4 <main>:
 80483c4:   8d 4c 24 04             lea    0x4(%esp),%ecx
 80483c8:   83 e4 f0                and    "151930920"xfffffff0,%esp
 80483cb:   ff 71 fc                pushl  -0x4(%ecx)
 80483ce:   55                      push   %ebp
 80483cf:   89 e5                   mov    %esp,%ebp
 80483d1:   51                      push   %ecx
 80483d2:   83 ec 04                sub    "151930920"x4,%esp
 80483d5:   c7 04 24 b0 84 04 08    movl   "151930920"x80484b0,(%esp)
 80483dc:   e8 13 ff ff ff          call   80482f4 <puts@plt>
 80483e1:   b8 00 00 00 00          mov    "151930920"x0,%eax
 80483e6:   83 c4 04                add    "151930920"x4,%esp 
 80483e9:   59                      pop    %ecx
 80483ea:   5d                      pop    %ebp
 80483eb:   8d 61 fc                lea    -0x4(%ecx),%esp
 80483ee:   c3                      ret
 80483ef:   90                      nop

et

$ objdump -d --disassembler-options=intel code.c
 080483c4 <main>:
 80483c4:   8d 4c 24 04             lea    ecx,[esp+0x4]
 80483c8:   83 e4 f0                and    esp,0xfffffff0
 80483cb:   ff 71 fc                push   DWORD PTR [ecx-0x4]
 80483ce:   55                      push   ebp
 80483cf:   89 e5                   mov    ebp,esp
 80483d1:   51                      push   ecx
 80483d2:   83 ec 04                sub    esp,0x4
 80483d5:   c7 04 24 b0 84 04 08    mov    DWORD PTR [esp],0x80484b0
 80483dc:   e8 13 ff ff ff          call   80482f4 <puts@plt>
 80483e1:   b8 00 00 00 00          mov    eax,0x0
 80483e6:   83 c4 04                add    esp,0x4
 80483e9:   59                      pop    ecx
 80483ea:   5d                      pop    ebp
 80483eb:   8d 61 fc                lea    esp,[ecx-0x4]
 80483ee:   c3                      ret    
 80483ef:   90                      nop
47
répondu amaterasu 2018-06-01 16:26:23

godbolt est un outil très utile, ils énumèrent seulement a compilateurs C++, mais vous pouvez utiliser le drapeau -x c afin de le faire traiter le code comme C. Il générera alors une liste d'assemblage pour votre code côte à côte et vous pouvez utiliser l'option Colourise pour générer des barres colorées pour indiquer visuellement quel code source correspond à l'assemblage généré. Par exemple le code suivant:

#include <stdio.h>

void func()
{
  printf( "hello world\n" ) ;
}

en utilisant la ligne de commande suivante:

-x c -std=c99 -O3

et Colourise généreraient ce qui suit:

enter image description here

33
répondu Shafik Yaghmour 2015-12-21 17:03:24

avez-vous essayé gcc -S -fverbose-asm -O source.c puis regarder dans le fichier source.s généré par l'assembleur ?

le code de l'assembleur généré va dans source.s (vous pouvez remplacer cela par -o assembleur-nom de fichier ); l'option -fverbose-asm demande au compilateur d'envoyer quelques commentaires de l'assembleur" expliquant " le code de l'assembleur généré. L'option -O demande au compilateur d'optimiser un peu (il pourrait optimiser plus avec -O2 ou -O3 ).

si vous voulez comprendre ce que fait gcc essayez de passer -fdump-tree-all mais soyez prudent: vous obtiendrez des centaines de fichiers dump.

BTW, GCC est extensible thru plugins ou avec FONDRE (un haut niveau de langage spécifique au domaine d'étendre GCC).

19
répondu Basile Starynkevitch 2016-01-30 23:29:58

vous pouvez utiliser gdb pour cela comme objdump.

cet extrait est tiré de http://sources.redhat.com/gdb/current/onlinedocs/gdb_9.html#SEC64


voici un exemple de source mixte+assemblage pour Intel x86:

  (gdb) disas /m main
Dump of assembler code for function main:
5       {
0x08048330 :    push   %ebp
0x08048331 :    mov    %esp,%ebp
0x08048333 :    sub    "151900920"x8,%esp
0x08048336 :    and    "151900920"xfffffff0,%esp
0x08048339 :    sub    "151900920"x10,%esp

6         printf ("Hello.\n");
0x0804833c :   movl   "151900920"x8048440,(%esp)
0x08048343 :   call   0x8048284 

7         return 0;
8       }
0x08048348 :   mov    "151900920"x0,%eax
0x0804834d :   leave
0x0804834e :   ret

End of assembler dump.
17
répondu Vishal Sagar 2011-08-15 11:18:06

utiliser le-s (Note: capital S) passer à GCC, et il émettra le code d'assemblage à un fichier avec A.s d'extension. Par exemple, la commande suivante:

gcc-O2-S-C foo.c

12
répondu codymanix 2009-08-17 19:24:42

Je n'ai pas donné de chance à gcc, mais en cas de g++. La commande ci-dessous fonctionne pour moi. -g pour la version debug et -Wa,-adhln est passé à l'assembleur pour l'inscription avec le code source

g++- g-Wa, - adhln src.cpp

4
répondu DAG 2016-03-30 06:00:56