Saya membaca pertanyaan lain mengenai efisiensi dua baris kode, dan OP mengatakan bahwa dia melihat perakitan di belakang kode dan kedua baris identik dalam perakitan. Digresi samping, bagaimana saya bisa melihat kode assembly yang dibuat ketika sebuah program dikompilasi.
Saya menggunakan Microsoft Visual C ++, tetapi saya juga ingin tahu apakah mungkin untuk melihat perakitan di belakang kode yang ditulis dalam Visual Basic.
Jadi, bagaimana cara melihat kode assembly di belakang program yang ditulis dalam bahasa tingkat tinggi seperti C ++ dan Visual Basic?
visual-c++
assembly
Bart
sumber
sumber
Jawaban:
Ada beberapa pendekatan:
Anda biasanya dapat melihat kode assembly saat men-debug C ++ di studio visual (dan juga eclipse). Untuk ini di Visual Studio, letakkan breakpoint pada kode yang dimaksud dan ketika debugger memukulnya, klik tepat dan temukan "Go To Assembly" (atau tekan CTRL + ALT + D)
Pendekatan kedua adalah menghasilkan daftar perakitan saat menyusun. Untuk ini, masuk ke pengaturan proyek -> C / C ++ -> Output Files -> ASM List Location dan isi nama file. Pilih juga "Assembly Output" ke "Assembly With Source Code".
Kompilasi program dan gunakan debugger pihak ketiga. Anda dapat menggunakan OllyDbg atau WinDbg untuk ini. Anda juga dapat menggunakan IDA (disassembler interaktif). Tapi ini cara hardcore untuk melakukannya.
sumber
Catatan tambahan: ada perbedaan besar antara keluaran assembler Debug dan keluaran satu. Yang pertama bagus untuk mempelajari bagaimana compiler menghasilkan kode assembler dari C ++. Yang kedua adalah baik untuk mempelajari bagaimana compiler mengoptimalkan berbagai konstruksi C ++. Dalam hal ini beberapa transformasi C ++ - ke-asm tidak jelas.
sumber
Tentukan sakelar / FA untuk kompilator cl. Bergantung pada nilai sakelar, baik hanya kode perakitan atau kode tingkat tinggi dan kode perakitan yang terintegrasi. Nama file mendapat ekstensi file .asm. Berikut adalah nilai yang didukung:
sumber
Cara termudah adalah dengan mengaktifkan debugger dan memeriksa jendela pembongkaran .
sumber
Versi sebelumnya dari jawaban ini ("retasan" untuk rextester.com) sebagian besar mubazir sekarang karena http://gcc.godbolt.org/ menyediakan CL 19 RC untuk ARM, x86, dan x86-64 (menargetkan konvensi pemanggilan Windows , tidak seperti gcc, clang, dan icc di situs itu).
Penjelajah kompilator Godbolt dirancang untuk memformat keluaran asm kompilator dengan baik, menghilangkan "noise" dari direktif, jadi saya sangat merekomendasikan menggunakannya untuk melihat asm untuk fungsi sederhana yang mengambil argumen dan mengembalikan nilai (jadi mereka tidak akan dioptimalkan).
Untuk sementara, CL tersedia di http://gcc.beta.godbolt.org/ tetapi bukan situs utama, tetapi sekarang tersedia di keduanya.
Untuk mendapatkan keluaran MSVC asm dari http://rextester.com/l/cpp_online_compiler_visual kompilator online: Tambahkan
/FAs
ke opsi baris perintah. Mintalah program Anda menemukan jalurnya sendiri dan mengerjakan jalur ke.asm
dan membuangnya. Atau jalankan disassembler di.exe
.mis. http://rextester.com/OKI40941
type
adalah versi DOS daricat
. Saya tidak ingin memasukkan lebih banyak kode yang akan membuat lebih sulit untuk menemukan fungsi yang ingin saya lihat asmnya. (Meskipun menggunakan std :: string dan boost run counter untuk tujuan tersebut! Beberapa manipulasi string gaya C yang membuat lebih banyak asumsi tentang string yang diprosesnya (dan mengabaikan keamanan / alokasi panjang-maksimal dengan menggunakan buffer besar) pada hasilGetModuleFileNameA
would menjadi lebih sedikit total kode mesin.)IDK mengapa, tetapi
cout << p.string() << endl
hanya menunjukkan nama dasar (yaitu nama file, tanpa direktori), meskipun pencetakan panjangnya menunjukkan itu bukan hanya nama kosong. (Chromium48 di Ubuntu 15.10). Mungkin ada beberapa pemrosesan backslash-escape di beberapa titikcout
, atau antara stdout program dan browser web.sumber
.c_str()
mencetak apa yang tampak seperti penunjuk. Jika Anda mengikuti tautan tersebut, Anda akan melihat kode ke hexdump astd::string
(dinonaktifkan dengan#if 0
). Ternyata string itu baik-baik saja, tetapicout
tidak membawanya ke browser web. Tidak ada karakter non-ascii juga, hanya garis miring terbalik.subdir--; p /= *subdir;
melakukannya bukankah Anda mengurangi p menjadi hanya nama file? Atau mungkin saya salah paham tentang apa yang Anda coba cetak.subdir--
diikuti olehp /= *subdir
kapansubdir
aslinyap.end()
GetModuleFileNameA
baru saja kembalia.exe
. Tidak sampai saya melakukan hexdump dan mencetak panjang yang saya tahu itu berfungsi, dan saya dapat meminta program memanipulasi jalur, saya tidak bisa mencetak jalur\\r
(baik\r
ketika kompilator mengeluarkannya) dari nama file yang diterjemahkan dengan buruk saat rendering untuk browser web. Menggunakanp.generic_string()
bekerja tetapi garis miring terbalik adalah garis miring ke depan.Dalam Visual C ++ opsi proyek di bawah, File Keluaran Saya percaya memiliki opsi untuk mengeluarkan daftar ASM dengan kode sumber. Jadi, Anda akan melihat kode sumber C / C ++ dan ASM yang dihasilkan semuanya dalam file yang sama.
sumber
Untuk MSVC Anda dapat menggunakan linker.
link.exe / dump / linenumbers / disasm /out:foo.dis foo.dll
foo.pdb harus tersedia untuk mendapatkan simbol
sumber
.NET Reflector dari Red Gate adalah alat yang cukup mengagumkan yang telah membantu saya lebih dari beberapa kali. Sisi positif dari utilitas ini selain menampilkan MSIL dengan mudah adalah bahwa Anda dapat menganalisis banyak DLL pihak ketiga dan meminta Reflector menangani pengubahan MSIL ke C # dan VB.
Saya tidak menjanjikan kode akan sejelas sumber tetapi Anda seharusnya tidak mengalami banyak kesulitan mengikutinya.
sumber
Jika Anda berbicara tentang debugging untuk melihat kode assembly, cara termudah adalah Debug-> Windows-> Disassembly (atau Alt-8). Ini akan memungkinkan Anda masuk ke fungsi yang dipanggil dan tetap dalam Pembongkaran.
sumber