Saya ingin mengajukan beberapa pertanyaan tentang bahasa Majelis. Pemahaman saya adalah bahwa itu sangat dekat dengan bahasa mesin, membuatnya lebih cepat dan lebih efisien.
Karena kita memiliki arsitektur komputer berbeda yang ada, apakah itu berarti saya harus menulis kode yang berbeda di Majelis untuk arsitektur yang berbeda? Jika demikian, mengapa bukan Assembly, menulis sekali - jalankan di mana saja jenis bahasa? Tidakkah akan lebih mudah untuk membuatnya universal, sehingga Anda hanya menulisnya sekali dan dapat menjalankannya di hampir semua mesin dengan konfigurasi yang berbeda? (Saya pikir itu tidak mungkin, tetapi saya ingin memiliki jawaban yang konkret dan mendalam)
Beberapa orang mungkin mengatakan C adalah bahasa yang saya cari. Saya belum pernah menggunakan C sebelumnya tetapi saya pikir itu masih bahasa tingkat tinggi, meskipun mungkin lebih cepat dari Jawa, misalnya. Saya mungkin salah di sini.
Jawaban:
Bahasa assembly adalah cara untuk menulis instruksi untuk set instruksi komputer , dengan cara yang sedikit lebih dimengerti oleh programmer manusia.
Arsitektur yang berbeda memiliki perangkat instruksi yang berbeda: perangkat instruksi yang diizinkan berbeda pada setiap arsitektur. Oleh karena itu, Anda tidak dapat berharap untuk memiliki program perakitan menulis-sekali-lari-di mana-mana. Sebagai contoh, set instruksi yang didukung oleh prosesor x86 terlihat sangat berbeda dari set instruksi yang didukung oleh prosesor ARM. Jika Anda menulis program perakitan untuk prosesor x86, itu akan memiliki banyak instruksi yang tidak didukung pada prosesor ARM, dan sebaliknya.
Alasan utama untuk menggunakan bahasa rakitan adalah karena hal itu memungkinkan kontrol tingkat yang sangat rendah atas program Anda, dan untuk mengambil keuntungan dari semua instruksi prosesor: dengan menyesuaikan program untuk memanfaatkan fitur yang unik untuk prosesor tertentu. akan berjalan terus, terkadang Anda bisa mempercepat program. Filosofi menulis-sekali-lari-di mana-mana pada dasarnya bertentangan dengan itu.
sumber
DEFINISI bahasa assembly adalah bahasa yang dapat diterjemahkan langsung ke kode mesin. Setiap kode operasi dalam bahasa assembly diterjemahkan menjadi tepat satu operasi di komputer target. (Yah, ini sedikit lebih rumit dari itu: beberapa assembler secara otomatis menentukan "mode pengalamatan" berdasarkan argumen ke kode-op. Tapi tetap saja, prinsipnya adalah bahwa satu jalur perakitan diterjemahkan menjadi satu instruksi bahasa mesin.)
Anda dapat, tidak diragukan lagi, menciptakan bahasa yang akan terlihat seperti bahasa rakitan tetapi akan diterjemahkan ke kode mesin yang berbeda pada komputer yang berbeda. Namun menurut definisi, itu bukan bahasa assembly. Itu akan menjadi bahasa tingkat tinggi yang menyerupai bahasa assembly.
Pertanyaan Anda sedikit seperti bertanya, "Apakah mungkin membuat perahu yang tidak melayang atau memiliki cara lain untuk melakukan perjalanan melintasi air, tetapi memiliki roda dan motor dan dapat melakukan perjalanan di darat?" Jawabannya adalah bahwa menurut definisi, kendaraan seperti itu tidak akan menjadi perahu. Kedengarannya lebih seperti mobil.
sumber
Tidak ada alasan konseptual (saya yakin, tidak ada ilmu komputer ) untuk tidak memiliki satu bahasa assembly untuk semua komputer di dunia. Bahkan, itu akan membuat banyak hal lebih mudah. Sejauh menyangkut teori, mereka semua sama saja, sampai pada beberapa peninggalan yang funky.
Dalam praktiknya, bagaimanapun, ada chip yang berbeda untuk tujuan yang berbeda, dengan operasi yang berbeda dan prinsip-prinsip desain (misalnya RISC vs CISC) yang melayani tujuan yang berbeda, dan set instruksi yang mengoperasikannya serta dengannya bahasa assembly berbeda. Pada akhirnya, jawabannya sama dengan ketika menanyakan mengapa ada begitu banyak bahasa pemrograman yang berbeda: tujuan yang berbeda, keputusan desain yang berbeda.
Yang mengatakan, Anda tentu saja dapat memperkenalkan level abstraksi untuk mendapatkan beberapa antarmuka bersama. x86, misalnya, telah dihapus dengan level chip untuk beberapa waktu; ada sedikit perangkat keras yang menerjemahkan instruksi x86 menjadi apa pun yang benar-benar bekerja dengan prosesor Anda . Bahasa seperti C akan menjadi langkah lain dari perangkat keras (jika bisa dibilang kecil), sampai ke bahasa seperti Haskell, Java atau Ruby. Ya, kompiler adalah salah satu pencapaian utama dari ilmu komputer karena mereka memungkinkan untuk memisahkan masalah dengan cara ini.
sumber
Anda menyebutkan frasa "tulis sekali dijalankan di mana saja" tanpa terlihat memerhatikan signifikansinya. Itulah slogan pemasaran untuk Sun Microsystems yang komersial menciptakan konsep "mesin virtual" dan "bytecode" untuk Java, meskipun mungkin ide mungkin berasal akademisi 1 st. Gagasan itu kemudian disalin oleh Microsoft untuk .Net setelah mereka berhasil digugat oleh Sun karena melanggar pelanggaran lisensi Java. Bytecode Java adalah implementasi dari ide perakitan lintas-mesin atau bahasa mesin. Mereka digunakan untuk beberapa bahasa selain Jawa dan secara teoritis dapat digunakan untuk mengkompilasi bahasa apa pun. Setelah bertahun-tahun optimasi yang sangat maju, Java mendekati kinerja untuk bahasa yang dikompilasi yang menunjukkan tujuan teknologi mesin agnostik platform-kinerja tinggi yang dapat dicapai secara umum.
Gagasan baru lainnya dalam tahap awal / sirkulasi terkait dengan kebutuhan Anda disebut proyek rekomputasi dan untuk penelitian ilmiah meskipun dapat digunakan untuk tujuan lain. Idenya adalah untuk membuat eksperimen komputasi dapat direplikasi melalui teknologi mesin virtual. Ini terutama ide mensimulasikan arsitektur mesin yang berbeda pada perangkat keras yang sewenang-wenang.
sumber
Alasan tingkat tinggi
Ketika Anda memikirkannya, mikroprosesor melakukan hal yang luar biasa: mikroprosesor memungkinkan Anda mengambil mesin (seperti mesin cuci atau lift), dan mengganti seluruh bagian dari mekanisme atau sirkuit yang dirancang khusus sesuai pesanan dengan silikon yang diproduksi secara massal murah keping Anda menghemat banyak uang untuk komponen, dan banyak waktu untuk desain.
Tapi tunggu dulu, chip standar , menggantikan desain khusus yang tak terhitung jumlahnya ? Tidak mungkin ada satu mikroprosesor tunggal yang sempurna untuk setiap aplikasi. Beberapa aplikasi perlu meminimalkan penggunaan daya tetapi tidak harus cepat; yang lain harus cepat tetapi tidak perlu mudah diprogram, yang lain harus murah, dll.
Jadi, kami memiliki banyak "rasa" mikroprosesor yang berbeda, masing-masing dengan kekuatan dan kelemahannya sendiri. Sangat diinginkan bagi mereka untuk semua menggunakan set instruksi yang kompatibel, karena ini memungkinkan penggunaan kembali kode dan membuatnya lebih mudah untuk menemukan orang dengan keterampilan yang tepat. Namun, set instruksi tidak memengaruhi biaya, kompleksitas, kecepatan, kemudahan penggunaan, dan kendala fisik prosesor, sehingga kami memiliki kompromi: ada beberapa set instruksi "arus utama" (dan banyak yang kecil), dan dalam setiap set instruksi ada banyak prosesor dengan karakteristik berbeda.
Oh, dan ketika teknologi berubah, semua pertukaran ini berubah, sehingga set instruksi berkembang, yang baru muncul, dan yang lama mati. Bahkan jika ada satu set instruksi "terbaik" hari ini, mungkin tidak dalam 20 tahun.
Detail perangkat keras
Mungkin keputusan desain terbesar dalam set instruksi adalah ukuran kata , yaitu seberapa besar angka yang dapat "dimanipulasi" prosesor secara alami. Prosesor 8-bit menangani angka dari 0-255, sedangkan prosesor 32-bit berurusan dengan angka dari 0 hingga 4.294.967.295. Kode yang dirancang untuk satu harus benar-benar dipikirkan kembali untuk yang lain.
Ini bukan hanya masalah menerjemahkan instruksi dari satu set instruksi ke instruksi lainnya. Pendekatan yang sangat berbeda mungkin lebih disukai dalam set instruksi yang berbeda. Sebagai contoh, pada prosesor 8-bit tabel pencarian mungkin ideal, sedangkan pada prosesor 32-bit operasi aritmatika akan lebih baik untuk tujuan yang sama.
Ada perbedaan besar lainnya antara set instruksi. Sebagian besar instruksi terbagi dalam empat kategori:
Prosesor berbeda dalam jenis komputasi apa yang dapat mereka lakukan, serta bagaimana mereka mendekati aliran kontrol, transfer data, dan konfigurasi prosesor.
Sebagai contoh, beberapa prosesor AVR tidak dapat menggandakan atau membagi; sedangkan semua prosesor x86 bisa. Seperti yang Anda bayangkan, menghilangkan sirkuit yang diperlukan untuk tugas-tugas seperti perkalian dan pembagian dapat membuat prosesor lebih sederhana dan lebih murah; operasi ini masih dapat dilakukan menggunakan rutin perangkat lunak jika diperlukan.
x86 memungkinkan instruksi aritmatika untuk memuat operan mereka dari memori dan / atau menyimpan hasilnya ke memori; ARM adalah arsitektur penyimpanan-toko dan karenanya hanya memiliki beberapa instruksi khusus untuk mengakses memori. Sementara itu x86 telah mendedikasikan instruksi cabang bersyarat, sementara ARM memungkinkan hampir semua instruksi dijalankan secara kondisional. Juga, ARM memungkinkan bit-shift dilakukan sebagai bagian dari sebagian besar instruksi aritmatika. Perbedaan-perbedaan ini menyebabkan karakteristik kinerja yang berbeda, perbedaan dalam desain internal dan biaya chip, dan perbedaan dalam teknik pemrograman di tingkat bahasa assembly.
Kesimpulan
Alasan mengapa tidak mungkin memiliki bahasa rakitan universal adalah bahwa, untuk mengubah kode rakitan dengan benar dari satu instruksi ke instruksi lainnya, seseorang harus mendesain ulang kode itu lagi — sesuatu yang belum bisa dilakukan oleh komputer.
sumber
Menambah jawaban yang luar biasa oleh DW: jika Anda ingin memiliki satu assembler, itu perlu mempertahankan semua arsitektur, penerjemah yang sempurna di antara mereka dan sepenuhnya memahami apa yang Anda lakukan.
Beberapa kode yang sangat dioptimalkan per satu arsitektur akan perlu dioptimalkan, dipahami pada tingkat yang lebih abstrak dan dioptimalkan satu sama lain.
Tetapi jika ini memungkinkan kami akan memiliki kompiler C yang sempurna, dan menulis dalam perakitan murni tidak akan bermanfaat sama sekali.
Poin utama menggunakan assembler adalah kinerja, yang tidak dapat diperas dari kompiler baru-baru ini.
Menulis program semacam itu akan lebih sulit daripada kompiler yang ada dan mempertahankan semua arsitektur baru yang sedang dibuat akan membuatnya lebih sulit.
Dan untuk program "satu-satunya", itu juga berarti kompatibilitas penuh mundur.
sumber
Microsoft menemukan MSIL sebagai bahasa rakitan perantara. Program akan dikompilasi dari C # atau VB.Net ke MSIL. Pada waktu berjalan, MSIL dikompilasi ke kode mesin untuk mesin yang menjalankannya menggunakan kompiler JIT . File yang berisi MSIL adalah file .EXE dengan beberapa instruksi di awal X86 untuk memulai program. Pada prosesor ARM, Anda harus mengetikkan kata mono di depan nama program untuk menjalankannya.
sumber
Sebagaimana dicatat, LLVM adalah hal yang paling dekat sejauh ini. Sebuah penghalang besar untuk bahasa yang benar-benar universal akan menjadi perbedaan mendasar yang terkait dengan pengorbanan implisit: konkurensi, penggunaan memori, throughput, latensi, dan konsumsi daya. Jika Anda menulis dengan gaya SIMD secara eksplisit, Anda mungkin menggunakan terlalu banyak memori. Jika Anda menulis dengan gaya SISD secara eksplisit, Anda akan mendapatkan paralelisasi suboptimal. Jika Anda mengoptimalkan untuk throughput, Anda sakit latensi. Jika Anda memaksimalkan throughput single-threaded (yaitu: kecepatan clock), Anda merusak masa pakai baterai.
Paling tidak, kode harus dianotasi dengan pengorbanan. Apa yang mungkin paling penting adalah bahasa tersebut memiliki sifat aljabar / tipe yang baik yang memberi kompiler banyak ruang gerak untuk mengoptimalkan dan mendeteksi inkonsistensi logis.
Lalu ada pertanyaan tentang perilaku yang tidak terdefinisi. Sebagian besar kecepatan bahasa C dan bahasa assembly berasal dari perilaku yang tidak terdefinisi. Jika Anda mengakui perilaku tidak terdefinisi yang benar-benar terjadi, maka Anda akhirnya menanganinya sebagai kasus khusus (yaitu: arsitektur dan peretas konteks tertentu).
sumber
Mungkin yang Anda cari adalah notasi Universal Turning Machine di mana semua orang menyetujui simbol untuk perintah. ( https://en.wikipedia.org/wiki/Universal_Turing_machine )
'Assembler' yang menerjemahkan bahasa Turning Acceptable ke kode mesin khusus vendor yang mendasarinya dan dibuat untuk hal-hal yang kita sebut komputer.
Dalam The Art of Computer Programming , ada contoh bagaimana ini terlihat.
Tetapi pertimbangkan pertanyaan "mengapa bahasa universal mereka tidak tersedia secara komersial yang dapat digunakan dengan semua komputer" Saya sarankan pengaruh yang paling dominan adalah (1) kenyamanan, tidak semua bahasa assembly adalah yang paling nyaman digunakan; (2) ekonomi, penyediaan, ketidakcocokan antara mesin dari berbagai merek dan vendor adalah strategi bisnis serta hasil dari sumber daya yang terbatas (waktu / uang) untuk merancang mesin.
sumber
asumsi: mengkompilasi dan mengoptimalkan bahasa tingkat tinggi L1 ke bahasa tingkat rendah L0 lebih mudah daripada menyusun dan mengoptimalkan bahasa tingkat tinggi L2 (lebih tinggi dari L1) ke L0; lebih mudah dalam arti bahwa Anda seharusnya dapat menghasilkan lebih banyak kode yang dioptimalkan ketika mengkompilasi L1 ke L0 daripada L2 ke L0.
Saya pikir anggapan itu mungkin benar, itulah sebabnya mungkin sebagian besar penyusun menggunakan bahasa tingkat menengah (IR / LLVM).
jika ini benar daripada menggunakan bahasa tingkat rendah L0 dan menulis kompiler untuk menerjemahkan L0 ke bahasa tingkat rendah lainnya. Misalnya, gunakan set instruksi MIPS, dan kompilasi ke x86, arm, power, ...
-Taoufik
sumber