Zastanawiałem się, jak użyć GCC na moim źródłowym pliku C do zrzucenia mnemonicznej wersji kodu maszynowego, aby zobaczyć, w jaki sposób mój kod jest kompilowany. Możesz to zrobić w Javie, ale nie byłem w stanie znaleźć sposobu w GCC.
Próbuję ponownie napisać metodę C w asemblerze i zobaczenie, jak działa GCC, byłoby bardzo pomocne.
Odpowiedzi:
Jeśli kompilujesz za pomocą symboli debugowania, możesz użyć
objdump
do uzyskania bardziej czytelnego demontażu.objdump -drwC -Mintel
jest miłe:-r
pokazuje nazwy symboli przy relokacjach (tak byś zobaczyłputs
wcall
instrukcji poniżej)-R
pokazuje relokacje dynamiczne / nazwy symboli (przydatne w bibliotekach współdzielonych)-C
rozróżnia nazwy symboli C ++-w
jest trybem „szerokim”: nie zawija bajtów kodu maszynowego do linii-Mintel
: użyj.intel_syntax noprefix
składni podobnej do GAS / binutils MASM zamiast AT&T-S
: przeplataj linie źródłowe z demontażem.Możesz umieścić coś takiego
alias disas="objdump -drwCS -Mintel"
w swoim~/.bashrc
Przykład:
źródło
-Wa,-adhln -g to gcc
. Zakłada się, że asemblerem jest gaz i nie zawsze tak jest.-Mintel
.Jeśli podasz GCC flagę
-fverbose-asm
, zrobi toźródło
objdump
-objdump -drwCS -Mintel
, więc jak mogę użyć czegoś takiego jakverbose
zobjdump
? Tak, że mogę mieć komentarze w kodzie asm, podobnie jak-fverbose-asm
w gcc?-fverbose-asm
dodawane są w postaci komentarzy w składni asm danych wyjściowych, a nie dyrektyw, które dodadzą coś dodatkowego w.o
pliku. Wszystko jest odrzucane w czasie montażu. Spójrz na dane wyjściowe asm kompilatora zamiast deasemblacji, np. Na godbolt.org, gdzie możesz łatwo dopasować go do linii źródłowej poprzez najechanie myszką i podświetlanie kolorów odpowiednich linii źródła / asm. Jak usunąć „szum” z wyjścia zespołu GCC / clang?Zgrane prosto z http://www.delorie.com/djgpp/v2faq/faq8_20.html (ale usunięcie błędne
-c
)źródło
gcc -march=native -O3 -save-temps
. Nadal możesz użyć,-c
aby zatrzymać tworzenie pliku obiektowego bez próby łączenia się, czy cokolwiek innego.-save-temps
jest interesujący, ponieważ zrzuca za jednym razem dokładnie wygenerowany kod, podczas gdy druga opcja wywoływania kompilatora-S
oznacza dwa razy kompilację i możliwe, że z różnymi opcjami. Ale-save-temps
zrzuca wszystko w bieżącym katalogu, co jest dość niechlujne. Wygląda na to, że jest bardziej przeznaczona jako opcja debugowania dla GCC niż narzędzie do sprawdzania kodu.Użycie
-S
przełącznika na GCC w systemach opartych na architekturze x86 powoduje domyślny zrzut składni AT&T, którą można określić za pomocą-masm=att
przełącznika:Natomiast jeśli chcesz utworzyć zrzut w składni Intela, możesz użyć
-masm=intel
przełącznika w następujący sposób:(Oba produkują zrzuty
code.c
do różnych składni do plikucode.s
)Aby uzyskać podobne efekty za pomocą objdump, powinieneś użyć przykładu
--disassembler-options=
intel
/att
switch (z zrzutami kodu, aby zilustrować różnice w składni):i
źródło
gcc -S -masm=intel test.c
nie dokładnie pracę dla mnie, mam jakąś krzyżówką Intel i AT & T składni tak:mov %rax, QWORD PTR -24[%rbp]
, zamiast tego:movq -24(%rbp), %rax
..o
plików ASM, tj. Via-Wa,-ahls -o yourfile.o yourfile.cpp>yourfile.asm
-M
opcja, jest taka sama,--disassembler-options
ale znacznie krótsza, np.objdump -d -M intel a.out | less -N
godbolt jest bardzo przydatnym narzędziem, lista zawiera tylko kompilatory C ++, ale możesz użyć
-x c
flagi, aby traktować kod jako C. Następnie wygeneruje listę zestawień dla twojego kodu obok siebie i możesz użyćColourise
opcji generowania kolorowe paski, aby wizualnie wskazać, który kod źródłowy odwzorowuje na wygenerowany zespół. Na przykład następujący kod:za pomocą następującego wiersza polecenia:
i
Colourise
wygeneruje następujące:źródło
-masm=intel
ale co z resztą?-x c
Czy próbowałeś
gcc -S -fverbose-asm -O source.c
wtedy zajrzeć do wygenerowanegosource.s
pliku asemblera?Wygenerowany kod asemblera przechodzi do
source.s
(możesz go przesłonić przez-o
asembler-filename );-fverbose-asm
opcja pyta kompilator emitować kilka uwag asemblera „wyjaśniające” wygenerowany kod asemblera.-O
Opcja pyta kompilator optymalizacji trochę (może to zoptymalizować więcej z-O2
lub-O3
).Jeśli chcesz zrozumieć, co
gcc
się dzieje, spróbuj przekazać,-fdump-tree-all
ale zachowaj ostrożność: otrzymasz setki plików zrzutu.BTW, GCC to rozszerzalne wtyczki lub MELT (język wysokiego poziomu specyficzny dla domeny, aby rozszerzyć GCC; którego porzuciłem w 2017 roku)
źródło
source.s
, ponieważ wiele osób spodziewałoby się wydruku na konsoli.-S -o-
zrzuca na standardowe wyjście.-masm=intel
jest pomocne, jeśli chcesz użyć składni NASM / YASM. (ale używaqword ptr [mem]
raczej niż tylkoqword
, więc bardziej przypomina Intel / MASM niż NASM / YASM). gcc.godbolt.org porządnie zrzuca zrzut: opcjonalnie usuwa wiersze tylko z komentarzami, nieużywane etykiety i dyrektywy asemblera.-Og
jest nawet lepiej niż-O1
. Oznacza „optymalizuj do debugowania” i tworzy asm bez zbyt wielu trudnych / trudnych do wykonania optymalizacji, które robią wszystko, co mówi źródło. Jest dostępny od gcc4.8, ale clang 3.7 wciąż go nie ma. IDK, jeśli zdecydowali się przeciw temu lub co.Możesz użyć gdb do tego typu objdump.
Ten fragment pochodzi z http://sources.redhat.com/gdb/current/onlinedocs/gdb_9.html#SEC64
Oto przykład pokazujący mieszane źródło + zestaw dla Intel x86:
źródło
set disassembly-flavor intel
polecenia.Użyj przełącznika -S (uwaga: duże S) do GCC, a on wyemituje kod asemblera do pliku z rozszerzeniem .s. Na przykład następujące polecenie:
gcc -O2 -S -c foo.c
źródło
Nie dałem strzału do gcc, ale w przypadku g ++. Poniższe polecenie działa dla mnie. -g dla kompilacji debugowania i -Wa, -adhln jest przekazywany do asemblera w celu wyświetlenia z kodem źródłowym
g ++ -g -Wa, -adhln src.cpp
źródło
użyj -Wa, -adhln jako opcji na gcc lub g ++, aby wygenerować wynik listowania na standardowe wyjście.
-Wa, ... dotyczy opcji wiersza poleceń dla części asemblera (uruchom w gcc / g ++ po kompilacji C / ++). Wywołuje jako wewnętrznie (as.exe w systemie Windows). Widzieć
> as --help
jako wiersz poleceń, aby zobaczyć więcej pomocy dla narzędzia asemblera w gcc
źródło