Czytałem kolejne pytanie dotyczące wydajności dwóch linii kodu, a OP powiedział, że spojrzał na assembler za kodem i obie linie były identyczne w asemblerze. Pomijając dygresję, jak mógłbym zobaczyć kod asemblera utworzony podczas kompilacji programu.
Używam Visual C ++ firmy Microsoft, ale chciałbym również wiedzieć, czy jest możliwe wyświetlenie zestawu za kodem napisanym w Visual Basic.
Jak więc wyświetlić kod asemblera za programem napisanym w językach wyższego poziomu, takich jak C ++ i Visual Basic?
visual-c++
assembly
Bart
źródło
źródło
Odpowiedzi:
Istnieje kilka podejść:
Zwykle można zobaczyć kod asemblera podczas debugowania C ++ w Visual Studio (i zaćmienie). W tym celu w programie Visual Studio umieść punkt przerwania w kodzie, o którym mowa, a gdy debugger go osiągnie, kliknij i znajdź „Przejdź do zestawu” (lub naciśnij CTRL + ALT + D)
Drugie podejście polega na generowaniu list asemblerów podczas kompilacji. W tym celu przejdź do ustawień projektu -> C / C ++ -> Pliki wyjściowe -> Lokalizacja listy ASM i wpisz nazwę pliku. Wybierz także „Wyjście zespołu” na „Zespół z kodem źródłowym”.
Skompiluj program i użyj dowolnego debuggera innej firmy. Możesz do tego użyć OllyDbg lub WinDbg. Możesz także użyć IDA (interaktywny dezasembler). Ale to hardkorowy sposób na zrobienie tego.
źródło
Dodatkowa uwaga: istnieje duża różnica między wyjściem debugowania asemblera a wydaniem. Pierwszym z nich jest nauczenie się, jak kompilator tworzy kod asemblera z C ++. Drugi to dobry sposób, aby dowiedzieć się, jak kompilator optymalizuje różne konstrukcje C ++. W tym przypadku niektóre przekształcenia C ++ na asm nie są oczywiste.
źródło
Określ przełącznik / FA dla kompilatora cl. W zależności od wartości przełącznika zintegrowany jest albo tylko kod montażowy, albo kod wysokiego poziomu i kod montażowy. Nazwa pliku otrzymuje rozszerzenie .asm. Oto obsługiwane wartości:
źródło
Najłatwiej jest odpalić debugger i sprawdzić okno dezasemblacji .
źródło
Wcześniejsza wersja tej odpowiedzi ("hack" dla rextester.com) jest teraz w większości zbędna, ponieważ http://gcc.godbolt.org/ udostępnia CL 19 RC dla ARM, x86 i x86-64 (celując w konwencję wywoływania systemu Windows , w przeciwieństwie do gcc, clang i icc na tej stronie).
Eksplorator kompilatora Godbolt jest przeznaczony do ładnego formatowania danych wyjściowych kompilatora asm, usuwania „szumu” dyrektyw, więc bardzo polecam używanie go do szukania prostych funkcji, które pobierają argumenty i zwracają wartość (więc nie będą zoptymalizowany z dala).
Przez jakiś czas CL był dostępny na http://gcc.beta.godbolt.org/, ale nie na głównej stronie, ale teraz jest na obu.
Aby uzyskać dane wyjściowe MSVC asm z http://rextester.com/l/cpp_online_compiler_visual kompilatora online: Dodaj
/FAs
do opcji wiersza poleceń. Niech twój program znajdzie własną ścieżkę, opracuje ścieżkę do.asm
pliku i zrzuci go. Lub uruchom dezasembler na.exe
.np. http://rextester.com/OKI40941
type
jest wersją DOScat
. Nie chciałem dołączać więcej kodu, który utrudniałby znalezienie funkcji, dla których chciałem zobaczyć asm. (Chociaż za pomocą std :: string i są sprzeczne impuls do tych celów! Niektóre C-styl manipulacji ciąg, który sprawia, że kolejne założenia o struny to przetwórstwo (i ignoruje max długości bezpieczeństwa / alokację przy użyciu duży bufor) na skutekGetModuleFileNameA
BĘDZIE być znacznie mniej całkowitym kodem maszynowym.)IDK dlaczego, ale
cout << p.string() << endl
pokazuje tylko podstawową nazwę (tj. Nazwę pliku bez katalogów), mimo że wypisanie jej długości pokazuje, że nie jest to tylko sama nazwa. (Chromium48 na Ubuntu 15.10). Prawdopodobnie w pewnym momenciecout
lub między standardowym wyjściem programu a przeglądarką internetową występuje pewne przetwarzanie ucieczki odwrotnym ukośnikiem .źródło
.c_str()
drukuje coś, co wygląda jak wskaźnik. Jeśli podążasz za linkiem, zobaczysz kod zrzutu szesnastkowegostd::string
(wyłączony za pomocą#if 0
). Okazuje się, że ciąg jest w porządku, alecout
nie przekazuje go do przeglądarki internetowej. Nie ma też żadnych znaków spoza zestawu ASCII, tylko ukośniki odwrotne.subdir--; p /= *subdir;
czy nie zredukowałeś p do samej nazwy pliku? A może źle rozumiem, co próbujesz wydrukować.subdir--
nastąpiło po tym,p /= *subdir
kiedysubdir
pierwotnie byłop.end()
GetModuleFileNameA
właśnie wracama.exe
. Dopiero gdy go przekręciłem i wydrukowałem długość, wiedziałem, że działa, i mogłem pozwolić programowi manipulować ścieżką, po prostu nie mogłem wydrukować ścieżki\\r
(dobrze,\r
kiedy kompilator ją wypisuje) część nazwy pliku, którą źle przetłumaczył podczas renderowania w przeglądarce internetowej. Używaniep.generic_string()
działa, ale ukośniki odwrotne są ukośnikami w przód.W języku Visual C ++ opcje projektu w obszarze Output Files, jak sądzę, mają opcję wyświetlania listy ASM z kodem źródłowym. Więc zobaczysz kod źródłowy C / C ++ i wynikowy ASM w tym samym pliku.
źródło
W przypadku MSVC możesz użyć konsolidatora.
link.exe / dump / Linnumbers / disasm /out:foo.dis foo.dll
Aby można było pobrać symbole, musi być dostępny plik foo.pdb
źródło
Odbłyśnik .NET firmy Red Gate to całkiem niesamowite narzędzie, które pomogło mi więcej niż kilka razy. Zaletą tego narzędzia poza łatwym wyświetlaniem MSIL jest to, że możesz przeanalizować wiele bibliotek DLL innych firm i zlecić Reflectorowi zajęcie się konwersją MSIL na C # i VB.
Nie obiecuję, że kod będzie tak czytelny jak źródło, ale nie powinieneś mieć większych problemów z jego śledzeniem.
źródło
Jeśli mówisz o debugowaniu, aby zobaczyć kod asemblera, najłatwiejszym sposobem jest Debug-> Windows-> Disassembly (lub Alt-8). Pozwoli ci to wejść do wywoływanej funkcji i pozostać w demontażu.
źródło