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.
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 verriezputs
dans l'instructioncall
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
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.
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é)
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
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:
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).
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.
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
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