Używanie GCC do tworzenia czytelnego montażu?
Zastanawiałem się, jak użyć GCC na moim pliku źródłowym C, aby zrzucić mnemoniczną wersję kodu maszynowego, aby zobaczyć, w co jest kompilowany mój kod. Możesz to zrobić z Javą, ale nie byłem w stanie znaleźć sposobu z GCC.
Próbuję ponownie napisać metodę C w assembly i widząc, jak robi to GCC, byłoby to bardzo pomocne.
9 answers
Jeśli kompilujesz z symbolami debugowania, możesz użyć objdump
, aby stworzyć bardziej czytelny demontaż.
>objdump --help
[...]
-S, --source Intermix source code with disassembly
-l, --line-numbers Include line numbers and filenames in output
objdump -drwC -Mintel
jest ładny:
-
-r
pokazuje nazwy symboli na relokacjach (więc zobaczyszputs
w instrukcjicall
poniżej) -
-R
pokazuje dynamicznie łączące relokacje / nazwy symboli (przydatne w bibliotekach współdzielonych) -
-C
demangles C++ nazwy symboli - Jest to tryb "szeroki", który nie zawija bajtów kodu maszynowego.]}
-
-Mintel
: użyj GAS / binutils MASM-like.intel_syntax noprefix
składnia zamiast AT & T -
-S
: przeplatać linie źródłowe z demontażem.
Możesz umieścić coś takiego alias disas="objdump -drwCS -Mintel"
w swoim ~/.bashrc
Przykład:
> 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-02 01:20:13
Chciałbym dodać do tych odpowiedzi, że jeśli podasz GCC flagę -fverbose-asm
, asembler, który emituje, będzie dużo jaśniejszy do odczytania.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-30 22:42:37
Użyj przełącznika-S (Uwaga: duże S) na GCC, a to spowoduje wysłanie kodu asemblera do pliku z .rozszerzenie S. Na przykład następujące polecenie:
gcc -O2 -S foo.c
Pozostawi wygenerowany kod złożenia w pliku foo.s.
Wyrwane prosto z http://www.delorie.com/djgpp/v2faq/faq8_20.html (ale usunięcie błędnych -c
)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-18 21:26:44
Użycie przełącznika -S
do GCC w systemach opartych na x86 powoduje domyślnie zrzut składni AT & T, który może być określony za pomocą przełącznika -masm=att
, Tak:
gcc -S -masm=att code.c
Natomiast jeśli chcesz stworzyć zrzut w składni Intela, możesz użyć przełącznika -masm=intel
w następujący sposób:
gcc -S -masm=intel code.c
(oba wytwarzają zrzuty code.c
do różnych składni, odpowiednio do pliku code.s
)
Aby uzyskać podobne efekty z objdump, powinieneś użyć --disassembler-options=
intel
/att
switch, przykład (z zrzutami kodu, aby zilustrować różnice w składni):
$ objdump -d --disassembler-options=att code.c
080483c4 <main>:
80483c4: 8d 4c 24 04 lea 0x4(%esp),%ecx
80483c8: 83 e4 f0 and $0xfffffff0,%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 $0x4,%esp
80483d5: c7 04 24 b0 84 04 08 movl $0x80484b0,(%esp)
80483dc: e8 13 ff ff ff call 80482f4 <puts@plt>
80483e1: b8 00 00 00 00 mov $0x0,%eax
80483e6: 83 c4 04 add $0x4,%esp
80483e9: 59 pop %ecx
80483ea: 5d pop %ebp
80483eb: 8d 61 fc lea -0x4(%ecx),%esp
80483ee: c3 ret
80483ef: 90 nop
I
$ 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-01 16:26:23
Godbolt jest bardzo użytecznym narzędziem, lista zawiera tylko kompilatory C++, ale możesz użyć flagi -x c
, aby traktować kod jako C. Następnie wygeneruje listę zestawów dla Twojego kodu obok siebie i możesz użyć opcji Colourise
, aby wygenerować kolorowe paski, aby wizualnie wskazać, który kod źródłowy mapuje do wygenerowanego zestawu. Na przykład następujący kod:
#include <stdio.h>
void func()
{
printf( "hello world\n" ) ;
}
Używając następującego wiersza poleceń:
-x c -std=c99 -O3
I Colourise
wygenerowałyby po:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-21 17:03:24
Czy próbowałeś gcc -S -fverbose-asm -O source.c
i zajrzałeś do wygenerowanego source.s
Pliku asemblera ?
Wygenerowany kod asemblera wchodzi do source.s
(można go zastąpić za pomocą -o
asembler-filename ); opcja -fverbose-asm
prosi kompilator o wysłanie uwag asemblera "wyjaśniających" wygenerowany kod asemblera. Opcja -O
prosi kompilator o bitową optymalizację (może zoptymalizować więcej za pomocą -O2
lub -O3
).
Jeśli chcesz zrozumieć co robi gcc
spróbuj przejść -fdump-tree-all
ale bądź ostrożnie: dostaniesz setki plików zrzutu.
BTW, GCC jest rozszerzalny poprzez wtyczki lub z MELT (język specyficzny dla domeny wysokiego poziomu do rozszerzenia GCC).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-30 23:29:58
Możesz użyć gdb do tego, jak objdump.
Ten fragment pochodzi z http://sources.redhat.com/gdb/current/onlinedocs/gdb_9.html#SEC64
Oto przykład pokazujący mixed source+assembly dla Intel x86:
(gdb) disas /m main Dump of assembler code for function main: 5 { 0x08048330 : push %ebp 0x08048331 : mov %esp,%ebp 0x08048333 : sub $0x8,%esp 0x08048336 : and $0xfffffff0,%esp 0x08048339 : sub $0x10,%esp 6 printf ("Hello.\n"); 0x0804833c : movl $0x8048440,(%esp) 0x08048343 : call 0x8048284 7 return 0; 8 } 0x08048348 : mov $0x0,%eax 0x0804834d : leave 0x0804834e : ret End of assembler dump.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-15 11:18:06
Użyj przełącznika-S (Uwaga: duże S) na GCC, a to spowoduje wysłanie kodu asemblera do pliku z .rozszerzenie S. Na przykład następujące polecenie:
Gcc-O2-S-C foo.c
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-17 19:24:42
Nie dałem szans gcc, ale w przypadku g++. Poniższe polecenie działa dla mnie. -g for debug build and-Wa, - adhln is passed to assembler for listing with source code
G++-G-Wa, - adhln src.cpp
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-30 06:00:56