Saya bingung tentang kode mesin dan kode asli dalam konteks bahasa .NET.
Apa perbedaan di antara keduanya? Apakah mereka sama?
.net
assembly
bytecode
machine-code
samaladeepak
sumber
sumber
Jawaban:
Istilah tersebut memang agak membingungkan, karena terkadang digunakan secara tidak konsisten.
Kode mesin: Ini yang paling jelas. Ini adalah kode yang menggunakan instruksi kode byte yang dipahami dan dijalankan oleh prosesor Anda (bagian fisik logam yang sebenarnya). Semua kode lainnya harus diterjemahkan atau diubah menjadi kode mesin sebelum mesin Anda dapat menjalankannya.
Kode asli: Istilah ini terkadang digunakan di tempat-tempat di mana kode mesin (lihat di atas) dimaksudkan. Namun, terkadang juga digunakan untuk mengartikan kode yang tidak terkelola (lihat di bawah).
Kode unmanaged dan kode dikelola: unmanaged code mengacu pada kode yang ditulis dalam bahasa pemrograman seperti C atau C ++, yang dikompilasi langsung ke kode mesin . Ini kontras dengan kode yang dikelola , yang ditulis dalam C #, VB.NET, Java, atau serupa, dan dieksekusi dalam lingkungan virtual (seperti .NET atau JavaVM) yang "mensimulasikan" prosesor dalam perangkat lunak. Perbedaan utamanya adalah kode terkelola "mengelola" sumber daya (sebagian besar alokasi memori) untuk Anda dengan menggunakan pengumpulan sampah dan dengan menjaga referensi ke objek tetap buram. Kode tidak terkelolaadalah jenis kode yang mengharuskan Anda mengalokasikan dan mengalokasikan memori secara manual, terkadang menyebabkan kebocoran memori (saat Anda lupa mengalokasikannya) dan terkadang kesalahan segmentasi (saat Anda membatalkan alokasi terlalu cepat). Tidak terkelola juga biasanya menyiratkan tidak ada pemeriksaan run-time untuk kesalahan umum seperti dereferensi penunjuk nol atau luapan batas array.
Sebenarnya, sebagian besar bahasa yang diketik secara dinamis - seperti Perl, Python, PHP dan Ruby - juga merupakan kode yang dikelola . Namun, mereka tidak secara umum dijelaskan seperti itu, yang menunjukkan bahwa kode terkelola sebenarnya merupakan istilah pemasaran untuk lingkungan pemrograman komersial yang sangat besar, serius, dan komersial (.NET dan Java).
Kode perakitan: Istilah ini umumnya mengacu pada jenis kode sumber yang ditulis orang ketika mereka benar-benar ingin menulis kode byte. Sebuah assembler adalah program yang mengubah kode sumber ini menjadi nyata byte-code. Ini bukan kompilator karena transformasinya 1-ke-1. Namun, istilah ini ambigu mengenai jenis kode byte yang digunakan: dapat dikelola atau tidak. Jika tidak dikelola, kode byte yang dihasilkan adalah kode mesin . Jika dikelola, ini menghasilkan kode byte yang digunakan di belakang layar oleh lingkungan virtual seperti .NET. Kode yang dikelola (misalnya C #, Java) dikompilasi ke dalam bahasa kode byte khusus ini, yang dalam kasus .NET disebut Common Intermediate Language (CIL) dan di Jawa disebut kode byte Java. Biasanya ada sedikit kebutuhan bagi programmer umum untuk mengakses kode ini atau menulis dalam bahasa ini secara langsung, tetapi ketika orang melakukannya, mereka sering menyebutnya sebagai kode assembly karena mereka menggunakan assembler untuk mengubahnya menjadi kode byte.
sumber
Apa yang Anda lihat saat Anda menggunakan Debug + Windows + Disassembly saat men-debug program C # adalah panduan yang baik untuk istilah-istilah ini. Berikut adalah versi yang dianotasi ketika saya menyusun program 'hello world' yang ditulis dalam C # dalam konfigurasi Rilis dengan pengoptimalan JIT diaktifkan:
Klik kanan jendela dan centang "Show Code Bytes" untuk mendapatkan tampilan serupa.
Kolom di sebelah kiri adalah alamat kode mesin. Nilainya dipalsukan oleh debugger, kodenya sebenarnya terletak di tempat lain. Tapi itu bisa di mana saja, tergantung pada lokasi yang dipilih oleh compiler JIT, jadi debugger mulai menomori alamat dari 0 pada awal metode.
Kolom kedua adalah kode mesin . Angka 1 dan 0 aktual yang dijalankan CPU. Kode mesin, seperti di sini, biasanya ditampilkan dalam hex. Ilustratif mungkin adalah bahwa 0x8B memilih instruksi MOV, byte tambahan yang ada untuk memberi tahu CPU dengan tepat apa yang perlu dipindahkan. Perhatikan juga dua jenis instruksi CALL, 0xE8 adalah panggilan langsung, 0xFF adalah instruksi panggilan tidak langsung.
Kolom ketiga adalah kode assembly . Perakitan adalah bahasa sederhana, dirancang untuk memudahkan penulisan kode mesin. Ini dibandingkan dengan C # yang dikompilasi ke IL. Kompiler yang digunakan untuk menerjemahkan kode assembly disebut "assembler". Anda mungkin memiliki Microsoft assembler di komputer Anda, nama yang dapat dieksekusi adalah ml.exe, ml64.exe untuk versi 64-bit. Ada dua versi umum bahasa assembly yang digunakan. Yang Anda lihat adalah yang digunakan Intel dan AMD. Di dunia open source, perakitan dalam notasi AT&T adalah hal biasa. Sintaks bahasa sangat bergantung pada jenis CPU yang dibuat, bahasa assembly untuk PowerPC sangat berbeda.
Oke, itu menangani dua istilah dalam pertanyaan Anda. "Kode asli" adalah istilah fuzzy, ini tidak jarang digunakan untuk mendeskripsikan kode dalam bahasa yang tidak terkelola. Mungkin instruktif adalah untuk melihat jenis kode mesin apa yang dihasilkan oleh kompilator C. Ini adalah versi 'hello world' di C:
Saya tidak memberi anotasi, terutama karena sangat mirip dengan kode mesin yang dihasilkan oleh program C #. Pemanggilan fungsi printf () sangat berbeda dari pemanggilan Console.WriteLine () tetapi yang lainnya hampir sama. Juga perhatikan bahwa debugger sekarang membuat alamat kode mesin yang sebenarnya dan itu sedikit lebih pintar tentang simbol. Efek samping dari membuat info debug setelah membuat kode mesin seperti yang sering dilakukan oleh kompiler yang tidak dikelola. Saya juga harus menyebutkan bahwa saya mematikan beberapa opsi pengoptimalan kode mesin untuk membuat kode mesin terlihat serupa. Kompiler C / C ++ memiliki lebih banyak waktu yang tersedia untuk mengoptimalkan kode, seringkali hasilnya sulit untuk ditafsirkan. Dan sangat sulit untuk di-debug.
Poin utama di sini adalah ada sangat sedikit perbedaan antara kode mesin yang dihasilkan dari bahasa yang dikelola oleh kompilator JIT dan kode mesin yang dihasilkan oleh kompilator kode asli. Yang merupakan alasan utama mengapa bahasa C # dapat bersaing dengan kompilator kode asli. Satu-satunya perbedaan nyata di antara mereka adalah panggilan fungsi dukungan. Banyak di antaranya diimplementasikan di CLR. Dan yang utama berputar di sekitar pengumpul sampah.
sumber
Kode asli dan kode mesin adalah hal yang sama - byte sebenarnya yang dieksekusi oleh CPU.
Kode assembly memiliki dua arti: satu adalah kode mesin yang diterjemahkan ke dalam bentuk yang lebih dapat dibaca manusia (dengan byte untuk instruksi yang diterjemahkan menjadi mnemonik pendek mirip kata seperti "JMP" (yang "melompat" ke tempat lain dalam kode). Yang lainnya adalah bytecode IL (byte instruksi yang dihasilkan oleh kompiler seperti C # atau VB, yang pada akhirnya akan diterjemahkan ke dalam kode mesin, tetapi belum) yang hidup dalam DLL atau EXE.
sumber
Dalam .NET, majelis berisi kode MS Intermediate Language (MSIL, terkadang CIL).
Ini seperti kode mesin 'tingkat tinggi'.
Saat dimuat, MSIL dikompilasi oleh kompiler JIT menjadi kode asli (kode mesin Intel x86 atau x64).
sumber