Kode perakitan vs Kode mesin vs Kode objek?

227

Apa perbedaan antara kode objek, kode mesin dan kode rakitan?

Bisakah Anda memberikan contoh visual tentang perbedaan mereka?

mmcdole
sumber
Saya juga ingin tahu dari mana nama "kode objek" berasal? Apa arti kata "objek" di dalamnya? Apakah itu terkait dengan pemrograman berorientasi objek atau hanya kebetulan nama?
SasQ
@ SasQ: Kode objek .
Jesse Good
Saya tidak bertanya tentang apa itu kode objek, Kapten Obvious. Saya bertanya tentang dari mana nama itu berasal dan mengapa ini disebut kode "objek".
BarbaraKwarc

Jawaban:

296

Kode mesin adalah kode biner (1 dan 0) yang dapat dieksekusi langsung oleh CPU. Jika Anda adalah untuk membuka file kode mesin dalam editor teks Anda akan melihat sampah, termasuk karakter tak patut ditulis (tidak, tidak mereka karakter tak patut ditulis;)).

Kode objek adalah bagian dari kode mesin yang belum dihubungkan ke program yang lengkap. Ini kode mesin untuk satu perpustakaan atau modul tertentu yang akan membuat produk jadi. Mungkin juga mengandung placeholder atau offset yang tidak ditemukan dalam kode mesin dari program yang diselesaikan. The linker akan menggunakan penampung tersebut dan offset untuk menghubungkan segala sesuatu bersama-sama.

Kode assembly adalah teks biasa dan (agak) kode sumber yang dapat dibaca manusia yang sebagian besar memiliki analog 1: 1 langsung dengan instruksi mesin. Ini dicapai dengan menggunakan mnemonik untuk instruksi aktual, register, atau sumber daya lainnya. Contohnya termasuk JMPdan MULTuntuk instruksi lompat dan multiplikasi CPU. Tidak seperti kode mesin, CPU tidak mengerti kode perakitan. Anda mengonversi kode rakitan menjadi mesin dengan menggunakan assembler atau kompiler , meskipun kami biasanya memikirkan kompiler yang terkait dengan bahasa pemrograman tingkat tinggi yang disarikan lebih jauh dari instruksi CPU.

Membangun program yang lengkap melibatkan penulisan kode sumber untuk program dalam bahasa majelis atau bahasa tingkat tinggi seperti C ++. Kode sumber dirakit (untuk kode rakitan) atau dikompilasi (untuk bahasa tingkat yang lebih tinggi) ke kode objek, dan masing-masing modul dihubungkan bersama untuk menjadi kode mesin untuk program akhir. Dalam hal program yang sangat sederhana, langkah penautan mungkin tidak diperlukan. Dalam kasus lain, seperti dengan IDE (lingkungan pengembangan terintegrasi) linker dan kompiler dapat dipanggil bersama. Dalam kasus lain, skrip make rumit atau file solusi dapat digunakan untuk memberi tahu lingkungan bagaimana membuat aplikasi akhir.

Ada juga bahasa yang ditafsirkan yang berperilaku berbeda. Bahasa yang ditafsirkan bergantung pada kode mesin dari program juru bahasa khusus. Pada tingkat dasar, seorang juru bahasa mem-parsing kode sumber dan segera mengonversi perintah ke kode mesin baru dan mengeksekusinya. Penerjemah modern, kadang-kadang juga disebut lingkungan runtime atau mesin virtual , jauh lebih rumit: mengevaluasi seluruh bagian kode sumber sekaligus, melakukan caching dan mengoptimalkan jika memungkinkan, dan menangani tugas manajemen memori yang kompleks. Bahasa yang ditafsirkan juga dapat dikompilasi sebelumnya ke bahasa perantara tingkat rendah atau bytecode, mirip dengan kode assembly.

Joel Coehoorn
sumber
24
+1: bagus, tapi agak menyederhanakan jawaban - tidak semua instruksi perakitan diterjemahkan 1: 1 ke instruksi mesin, dan file objek juga dapat berisi data lain (informasi relokasi, tabel simbol, ...)
Christoph
5
Menambahkan kata musang untuk masalah pertama Anda, diedit untuk membuat 2nd lebih jelas.
Joel Coehoorn
2
@Christoph: Anda mengatakan "tidak semua instruksi perakitan diterjemahkan 1: 1 ke instruksi mesin" tolong beri contoh.
Olof Forshell
5
@Olof: Arsitektur RISC kadang-kadang menyediakan set instruksi virtual tingkat perakitan - misalnya MIPS instruksi semu ( en.wikipedia.org/wiki/MIPS_architecture#Pseudo_instructions )
Christoph
3
@ Panzercrisis Tidak ada yang ditambahkan oleh assembler. Ini adalah terjemahan langsung dari apa yang Anda tulis ke instruksi mesin yang sebenarnya. Dan saya tidak akan menyebut kode tambahan yang dimasukkan oleh kompiler "tidak perlu"
Joel Coehoorn
125

Jawaban lainnya memberikan deskripsi yang baik tentang perbedaannya, tetapi Anda juga meminta visual. Berikut adalah diagram yang menunjukkan perjalanan mereka dari kode C ke executable.

Grafik Noob
sumber
3
Saya merasa ini sangat membantu, tetapi tidak ada label "Kode mesin"
Alexx Roche
Jadi ketika itu pada tingkat kode yang dapat dieksekusi, apakah itu setara dengan kode mesin?
CMCDragonkai
3
Dalam konteks diagram ini, "kode objek" adalah kode mesin.
Grafik Noob
5
Sebenarnya, kode objek dan kode yang dapat dieksekusi adalah kode mesin. perbedaannya adalah bahwa kode objek bukan program yang selesai. Kode ini perlu dikombinasikan dengan kode perpustakaan / modul pembantu lain seperti yang ditunjukkan pada diagram untuk membentuk program / kode yang dapat dieksekusi lengkap.
okey_on
@okeyxyz pada tingkat apa akan benar untuk mengatakan itu langsung dieksekusi oleh prosesor? Setelah assembler, setelah linker, setelah loader, setelah itu dikonversi ke mikrokontroler?
Celeritas
49

Kode assembly adalah representasi kode mesin yang dapat dibaca manusia:

mov eax, 77
jmp anywhere

Kode mesin adalah kode heksadesimal murni:

5F 3A E3 F1

Saya berasumsi maksud Anda kode objek seperti dalam file objek. Ini adalah varian dari kode mesin, dengan perbedaan bahwa lompatan semacam parameter sehingga linker dapat mengisinya.

Assembler digunakan untuk mengubah kode assembly menjadi kode mesin (kode objek). Linker menghubungkan beberapa objek (dan pustaka) file untuk menghasilkan file yang dapat dieksekusi.

Saya pernah menulis program assembler dalam hex murni (tidak ada assembler tersedia) untungnya ini adalah jalan kembali pada 6502. tua yang baik (kuno). Tapi saya senang ada assembler untuk opium pentium.

Toon Krijthe
sumber
76
Tidak tidak tidak tidak. Kode mesin bukan kode hex. itu biner murni. Kode hex hanyalah representasi biner yang nyaman.
Breton
56
Jika kita benar-benar pergi ke ekstrem, itu bukan biner, itu adalah jumlah listrik yang tersimpan dalam suatu rangkaian. ;-)
Toon Krijthe
17
Ya tentu saja. Ada hubungan antara hexidecimal, dan apa yang Anda sebut "Kode Mesin", tetapi tidak cukup akurat untuk mengatakan hexidecimal adalah kode mesin. Itu saja yang ingin saya katakan.
Breton
9
@Reton Dalam pengertian itu, tidak ada yang namanya "kode hex" kan? "Hex code" hanyalah cara melihat kode mesin. Anda dapat melihat kode mesin dalam heksadesimal, biner, oktal, desimal, atau sesuka Anda. Juga lagi dalam pengertian itu, tidak ada "kode biner" juga. Sekali lagi, "kode biner" hanyalah cara melihat kode mesin.
Utku
9
@Breton Apa yang Anda katakan tidak terlalu masuk akal .. Biner adalah cara representasi, seperti hex. Jika bukan hex, itu juga bukan biner.
Koray Tugay
18

8B 5D 32 adalah kode mesin

mov ebx, [ebp+32h] adalah perakitan

lmylib.somengandung 8B 5D 32adalah kode objek

Quassnoi
sumber
8

Satu hal yang belum disebutkan adalah bahwa ada beberapa jenis kode rakitan. Dalam bentuk paling dasar, semua angka yang digunakan dalam instruksi harus ditentukan sebagai konstanta. Sebagai contoh:

$ 1902: BD 37 14: LDA $ 1437, X
$ 1905: 85 03: STA $ 03
$ 1907: 85 09: STA $ 09
$ 1909: CA: DEX
$ 190A: 10: BPL $ 1902

Bit kode di atas, jika disimpan di alamat $ 1900 dalam kartrid Atari 2600, akan menampilkan sejumlah garis dengan warna berbeda yang diambil dari tabel yang dimulai dari alamat $ 1437. Pada beberapa alat, mengetikkan alamat, bersama dengan bagian paling kanan dari baris di atas, akan menyimpan ke memori nilai-nilai yang ditunjukkan di kolom tengah, dan mulai baris berikutnya dengan alamat berikut. Mengetik kode dalam bentuk itu jauh lebih nyaman daripada mengetikkan hex, tetapi orang harus tahu alamat yang tepat dari semuanya.

Kebanyakan assembler memungkinkan seseorang untuk menggunakan alamat simbolis. Kode di atas akan ditulis lebih seperti:

rainbow_lp:
  lda ColorTbl, x
  WSYNC
  STA COLUBK
  dex
  bpl rainbow_lp

Assembler akan secara otomatis menyesuaikan instruksi LDA sehingga akan merujuk ke alamat apa pun yang dipetakan ke label ColorTbl. Menggunakan gaya assembler ini membuatnya lebih mudah untuk menulis dan mengedit kode daripada yang mungkin terjadi jika seseorang harus mengunci tangan dan merawat semua alamat dengan tangan.

supercat
sumber
1
+1. Satu lagi poin tambahan: ada juga sintaksis bahasa assembly yang berbeda , yang paling terkenal adalah Intel dan AT&T .
informatik01
1
@ informatik01: Bagaimana dengan Intel 8080 mnemonics vs Zilog Z80? Saya kira itu sebelum perang sintaks Intel vs AT&T.
supercat
Tidak berdebat, saya hanya menyebutkan aspek itu (sintaks berbeda) dan memberi contoh dua sintaksis paling terkenal / terkenal / terkenal.
informatik01
4

Kode sumber, kode perakitan, kode mesin, kode objek, kode byte, file yang dapat dieksekusi dan file perpustakaan.

Semua istilah ini sering sangat membingungkan bagi kebanyakan orang karena mereka pikir mereka saling eksklusif . Lihat diagram untuk memahami hubungan mereka. Deskripsi setiap istilah diberikan di bawah ini.


Jenis kode


Kode sumber

Instruksi dalam bahasa (pemrograman) yang dapat dibaca manusia


Kode tingkat tinggi

Instruksi ditulis dalam bahasa tingkat tinggi (pemrograman)
misalnya, program C, C ++ dan Java


Kode perakitan

Instruksi ditulis dalam bahasa assembly (semacam bahasa pemrograman tingkat rendah). Sebagai langkah pertama dari proses kompilasi, kode tingkat tinggi dikonversi ke dalam formulir ini. Ini adalah kode rakitan yang kemudian dikonversi menjadi kode mesin aktual. Pada kebanyakan sistem, kedua langkah ini dilakukan secara otomatis sebagai bagian dari proses kompilasi.
mis. program.asm


Kode objek

Produk dari proses kompilasi. Mungkin dalam bentuk kode mesin atau kode byte.
mis. file.o


Kode mesin

Instruksi dalam bahasa mesin.
misalnya, keluar


Kode byte

Instruksi dalam bentuk perantara yang dapat dieksekusi oleh penerjemah seperti JVM.
misal, file kelas Java


File yang dapat dieksekusi

Produk menghubungkan proses. Mereka adalah kode mesin yang dapat langsung dieksekusi oleh CPU.
misalnya, file .exe.

Perhatikan bahwa dalam beberapa konteks file yang berisi instruksi kode-byte atau bahasa scripting juga dapat dianggap dapat dieksekusi.


File perpustakaan

Beberapa kode dikompilasi ke dalam formulir ini untuk alasan yang berbeda seperti penggunaan kembali dan kemudian digunakan oleh file yang dapat dieksekusi.

Bertram Gilfoyle
sumber
1
Saya berpendapat bahwa tidak semua perakitan benar-benar sumber dalam arti ketat kode yang ditulis dan / atau dikelola oleh manusia. Seringkali ini dihasilkan oleh mesin dari sumber, dan tidak pernah dimaksudkan untuk konsumsi manusia (misalnya, gcc benar-benar membuat teks asm yang diumpankan ke assembler terpisah, alih-alih memiliki assembler internal di dalam cc1executable). Saya pikir lingkaran asm harus menjulurkan sisi kiri lingkaran "sumber", karena beberapa asm hanya asm, bukan sumber. Itu tidak pernah kode objek , tentu saja, tetapi beberapa asm adalah langkah dalam perjalanan dari sumber ke file objek.
Peter Cordes
@PeterCordes Terima kasih banyak atas komentarnya. Saya tidak tahu apa yang Anda katakan tentang cara kerja gcc. Namun, saya khawatir jika saya bisa setuju dengan Anda sepenuhnya. Yang saya maksud adalah, kode sumber adalah sesuatu yang ditulis menggunakan bahasa pemrograman yang dapat dibaca manusia. Itu mungkin atau mungkin tidak ditulis atau dikelola oleh manusia. Saya yakin Anda akan mengetahui transkompiler. Dari sudut pandang Anda, ke kategori mana Anda akan meletakkan produk dari kompiler seperti itu? Kode sumber atau yang lainnya? Harap perbaiki saya jika saya salah. Komentar lebih lanjut selalu diterima.
Bertram Gilfoyle
1

Kode perakitan dibahas di sini .

"Bahasa assembly adalah bahasa tingkat rendah untuk pemrograman komputer. Ini mengimplementasikan representasi simbolik dari kode mesin numerik dan konstanta lain yang diperlukan untuk memprogram arsitektur CPU tertentu."

Kode mesin dibahas di sini .

"Kode mesin atau bahasa mesin adalah sistem instruksi dan data yang dieksekusi langsung oleh unit pemrosesan pusat komputer."

Pada dasarnya, kode assembler adalah bahasa dan diterjemahkan ke kode objek (kode asli yang dijalankan CPU) oleh assembler (analog dengan kompiler).

rbrayb
sumber
1

Saya pikir ini adalah perbedaan utama

  • keterbacaan kode
  • kontrol atas apa yang kode Anda lakukan

Keterbacaan dapat membuat kode ditingkatkan atau diganti 6 bulan setelah itu dibuat dengan upaya litte, di sisi lain, jika kinerja sangat penting Anda mungkin ingin menggunakan bahasa tingkat rendah untuk menargetkan perangkat keras spesifik yang akan Anda miliki dalam produksi, sehingga untuk mendapatkan eksekusi lebih cepat.

IMO saat ini komputer cukup cepat untuk membiarkan seorang programmer mendapatkan eksekusi cepat dengan OOP.

Alberto Zaccagni
sumber
1

Assembly adalah istilah deskriptif pendek yang dapat dipahami manusia yang dapat langsung diterjemahkan ke dalam kode mesin yang sebenarnya digunakan CPU.

Meskipun agak dimengerti oleh manusia, Assembler masih level rendah. Dibutuhkan banyak kode untuk melakukan sesuatu yang bermanfaat.

Jadi alih-alih kami menggunakan bahasa tingkat yang lebih tinggi seperti C, BASIC, FORTAN (OK saya tahu saya sudah berkencan sendiri). Ketika dikompilasi ini menghasilkan kode objek. Bahasa awal memiliki bahasa mesin sebagai kode objek mereka.

Banyak bahasa saat ini seperti JAVA dan C # biasanya dikompilasi menjadi bytecode yang bukan kode mesin, tetapi yang mudah ditafsirkan pada saat dijalankan untuk menghasilkan kode mesin.

Jim C
sumber
Komentar Anda tentang Java dan C # - keduanya menggunakan kompilasi Just In Time sehingga bytecodes tidak diinterpretasikan. C # (.NET umumnya) mengkompilasi ke Bahasa Menengah (IL) yang kemudian JIT ke bahasa mesin asli untuk CPU target.
Craig Shearer
-1

File sumber dari program Anda dikompilasi menjadi file objek, dan kemudian linker menautkan file objek tersebut bersama-sama, menghasilkan file yang dapat dieksekusi termasuk kode mesin arsitektur Anda.

Baik file objek maupun file yang dapat dieksekusi melibatkan kode mesin arsitektur dalam bentuk karakter yang dapat dicetak dan yang tidak dapat dicetak saat dibuka oleh editor teks.

Meskipun demikian, dikotomi antara file adalah bahwa file objek dapat berisi referensi eksternal yang tidak terselesaikan (seperti printf, misalnya). Jadi, itu mungkin perlu dihubungkan dengan file objek lain .. Artinya, referensi eksternal yang belum terselesaikan perlu diselesaikan untuk mendapatkan file executable yang layak dijalankan dengan menghubungkan dengan file objek lain seperti C / C ++ runtime library's .

snr
sumber