Kita sering diberi tahu bahwa perangkat keras itu tidak peduli bahasa apa yang ditulis oleh sebuah program karena hanya melihat kode biner yang dikompilasi, namun ini bukan kebenaran sebenarnya. Misalnya, perhatikan Z80 yang sederhana; ekstensi ke set instruksi 8080 mencakup instruksi seperti CPIR yang berguna untuk memindai string gaya-C (dihentikan-NULL), misalnya untuk melakukan strlen()
. Para desainer harus mengidentifikasi bahwa menjalankan program C (sebagai lawan dari Pascal, di mana panjang string ada di header) adalah sesuatu yang mungkin digunakan untuk desain mereka. Contoh klasik lainnya adalah Mesin Lisp .
Apa contoh lain yang ada? Misalnya instruksi, jumlah dan jenis register , mode pengalamatan, yang membuat prosesor tertentu menyukai konvensi bahasa tertentu? Saya khususnya tertarik pada revisi keluarga yang sama.
sizeof(int)
sama dengan 1 harus mengharuskan jenischar
itu ditandatangani (karenaint
harus dapat menampung semua nilai jenischar
). Saya telah menulis kode untuk mesin di manachar
danint
keduanya bilangan bulat bertanda 16-bit; kesulitan terbesar adalah bahwa seseorang tidak dapat menggunakan serikat untuk konversi tipe, dan penyimpanan efisien dari sejumlah besar byte memerlukan pengemasan dan pembongkaran manual. Masalah-masalah itu kecil dibandingkan dengan kemungkinan dalam C yang sizeof (int) == sizeof (panjang), karena ...unsigned int
nilai. C99 memperbaiki situasi itu, tetapi sebelum C99 tidak ada cara satu langkah yang dijamin aman untuk membandingkan nilai yang berpotensi negatif dengan nilai tipeunsigned int
(orang harus menguji apakah jumlahnya negatif sebelum melakukan perbandingan).Jawaban:
Jawaban yang ada fokus pada perubahan ISA . Ada perubahan perangkat keras lain juga. Misalnya, C ++ biasanya menggunakan vtables untuk panggilan virtual. Dimulai dengan Pentium M , Intel memiliki komponen "predictor cabang tidak langsung" yang mempercepat panggilan fungsi virtual.
sumber
Set instruksi Intel 8086 mencakup variasi "ret" yang menambahkan nilai ke penunjuk tumpukan setelah membuka alamat pengirim. Ini berguna untuk banyak implementasi Pascal di mana pemanggil suatu fungsi akan mendorong argumen ke stack sebelum melakukan pemanggilan fungsi, dan mematikannya setelahnya. Jika sebuah rutin menerima misalnya parameter bernilai empat byte, itu bisa diakhiri dengan "RET 0004" untuk membersihkan tumpukan. Jika tidak ada instruksi seperti itu, konvensi pemanggilan seperti itu mungkin akan mengharuskan kode untuk membuka kembali alamat ke register, memperbarui penunjuk tumpukan, dan kemudian melompat ke register itu.
Menariknya, sebagian besar kode (termasuk rutinitas OS) pada Macintosh asli menggunakan konvensi pemanggilan Pascal meskipun tidak ada instruksi fasilitasi di 68000. Menggunakan konvensi pemanggilan ini menyimpan 2-4 byte kode di situs panggilan biasa, tetapi membutuhkan tambahan 4-6 byte kode di situs kembali setiap fungsi yang mengambil parameter.
sumber
ENTER
mitra untuk iniRET n
...ENTER
ada di 8086 yang asli; itu datang dengan prosesor kemudian. Itu memang memunculkan poin yang menarik, meskipun: mode pengalamatan berbasis BP jelas dirancang di sekitar penggunaan parameter bertumpuk dan penduduk lokal diakses melalui frame pointer. Saya menemukan konvensi ini menarik dalam beberapa cara, terutama mengingat (1) kode bahasa rakitan murni lebih cenderung menggunakan nilai dalam register daripada tumpukan, tetapi (2) keuntungan dari [BP + nn] menangani lebih dari [SP + nn] menangani lebih penting untuk program bahasa assembly yang mengakses berbagai hal di stack daripada ...Salah satu contoh adalah MIPS, yang memiliki keduanya
add
danaddu
untuk menjebak dan mengabaikan overflow masing-masing. (Jugasub
dansubu
.) Dibutuhkan jenis instruksi pertama untuk bahasa seperti Ada (saya pikir - saya belum pernah benar-benar menggunakan Ada) yang menangani overflow secara eksplisit dan tipe kedua untuk bahasa seperti C yang mengabaikan overflow.Jika saya ingat dengan benar, CPU sebenarnya memiliki beberapa sirkuit tambahan di ALU untuk melacak kelebihan. Jika satu-satunya bahasa yang dipedulikan orang adalah C, tidak perlu ini.
sumber
nmemb*size+offset
byte dan perlu memastikan bahwa Anda tidak mendapatkan overflow.addu
dansubu
instruksi (yang tidak memeriksa luapan) adalah yang ditambahkan untuk membuat C bahagia. Tentu saja, saya tidak benar-benar tahu - kami hanya membahasnya secara samar-samar dalam perkuliahan dan saya jelas bukan ahli dalam arsitektur: P.Seri Burroughs 5000 dirancang untuk secara efisien mendukung ALGOL, dan Intel iAPX-432 dirancang untuk secara efisien mengeksekusi Ada. Inmos Transputer memiliki bahasa sendiri, Occam. Saya pikir prosesor "Propeller" Parallax dirancang untuk diprogram menggunakan varian BASIC-nya sendiri.
Ini bukan bahasa, tetapi set instruksi VAX-11 memiliki satu instruksi untuk memuat konteks proses, yang dirancang setelah permintaan dari tim desain VMS. Saya tidak ingat detailnya, tetapi ISTR butuh begitu banyak instruksi untuk diimplementasikan sehingga menempatkan batas atas yang serius pada jumlah proses yang dapat mereka jadwalkan.
sumber
Satu hal yang tampaknya tidak disebutkan oleh siapa pun sejauh ini adalah bahwa kemajuan dalam optimisasi kompiler (di mana bahasa dasar sebagian besar tidak relevan) mendorong pergeseran dari set instruksi CISC (yang sebagian besar dirancang untuk dikodekan oleh manusia) ke set instruksi RISC (yang sebagian besar dirancang untuk dikodekan oleh kompiler.)
sumber
Keluarga Motorola 68000 memperkenalkan beberapa metode alamat otomatis yang membuat menyalin data melalui cpu sangat efisien dan ringkas.
[Contoh yang diperbarui]
ini adalah beberapa kode c ++ yang mempengaruhi 68000 assembler
diimplementasikan dalam assembler konvensional (pseudocode, saya lupa perintah 68000 assembler)
dengan adressmode baru itu menjadi sesuatu yang serupa
hanya dua instruksi per loop, bukan 4.
sumber
Mainframe seri Z IBM, adalah keturunan dari IBM 360 dari tahun 1960-an.
Ada beberapa instruksi yang ditujukan khusus untuk mempercepat program COBOL dan Fortran. Contoh klasik adalah
BXLE
- "Cabang pada Indeks Rendah Atau Setara" yang sebagian besar darifor
loop Fortran atau COBOLPERFORM VARYING x from 1 by 1 until x > n
dienkapsulasi dalam satu instruksi.Ada juga seluruh keluarga instruksi desimal dikemas untuk mendukung aritmatika desimal titik tetap yang umum dalam program COBOL.
sumber
DO
loop FORTRAN .Intel CPU awal memiliki fitur-fitur berikut, banyak dari mereka sekarang usang dalam mode 64-bit:
Tanda bendera, ditemukan dalam register status banyak CPU, ada untuk dengan mudah melakukan aritmatika yang ditandatangani DAN tidak ditandatangani.
Set instruksi SSE 4.1 memperkenalkan instruksi untuk pemrosesan string, baik yang dihitung maupun yang diakhiri nol (PCMPESTR, dll.)
Juga, saya dapat membayangkan bahwa sejumlah fitur tingkat sistem dirancang untuk mendukung keamanan kode yang dikompilasi (pengecekan batas segmen, gerbang panggilan dengan penyalinan parameter, dll.)
sumber
Beberapa prosesor ARM, terutama yang ada di perangkat seluler, termasuk (d) ekstensi Jazelle, yang merupakan interpreter JVM perangkat keras; itu mengartikan bytecode Java secara langsung. Jazelle-aware JVM dapat menggunakan perangkat keras untuk mempercepat eksekusi dan menghilangkan banyak JIT, tetapi mundur ke perangkat lunak VM masih dipastikan jika bytecode tidak dapat diartikan pada chip.
Prosesor dengan unit tersebut termasuk instruksi BXJ, yang menempatkan prosesor dalam "mode Jazelle" khusus, atau jika mengaktifkan unit telah gagal, itu hanya ditafsirkan sebagai instruksi cabang normal. Unit menggunakan kembali register ARM untuk menahan status JVM.
Penerus teknologi Jazelle adalah ThumbEE
sumber
Sejauh yang saya tahu ini lebih umum di masa lalu.
Ada sesi pertanyaan di mana James Gosling mengatakan bahwa ada orang yang mencoba membuat perangkat keras yang dapat menangani bytecode JVM dengan lebih baik, tetapi kemudian orang-orang ini akan menemukan cara untuk melakukannya dengan "x" umum intel x86 umum (mungkin mengkompilasi bytecode dalam beberapa cara pintar).
Dia menyebutkan bahwa ada keuntungan dalam menggunakan chip populer generik (seperti intel) karena memiliki perusahaan besar yang mengeluarkan sejumlah besar uang pada produk tersebut.
Video ini layak untuk dicoba. Dia membicarakan hal ini pada menit 19 atau 20.
sumber
Saya melakukan pencarian halaman cepat dan tampaknya tidak ada yang menyebutkan CPU yang dikembangkan secara khusus untuk mengeksekusi Forth . The bahasa pemrograman Forth adalah tumpukan berbasis, kompak, dan digunakan dalam sistem kontrol.
sumber
The Intel iAPX CPU secara khusus dirancang untuk bahasa OO. Tapi tidak cukup berhasil.
sumber
68000 memiliki MOVEM yang paling cocok untuk mendorong banyak register ke stack dalam satu instruksi yang merupakan apa yang diharapkan banyak bahasa.
Jika Anda melihat MOVEM (MOVE Multiple) sebelumnya JSR (Jump SubRoutine) di seluruh kode, maka Anda umumnya tahu bahwa Anda berurusan dengan kode yang dipenuhi C.
MOVEM diizinkan untuk penambahan otomatis register tujuan yang memungkinkan setiap penggunaan untuk melanjutkan penumpukan pada tujuan, atau menghapus dari tumpukan jika terjadi penurunan otomatis.
http://68k.hax.com/MOVEM
sumber
Arsitektur AVR Atmel sepenuhnya dirancang dari bawah ke atas agar sesuai untuk pemrograman dalam C. Sebagai contoh, catatan aplikasi ini menguraikan lebih jauh.
IMO ini terkait erat dengan jawaban yang sangat baik dari rockets4kids , dengan PIC16-s awal dikembangkan untuk pemrograman assembler langsung (total 40 instruksi), dengan keluarga kemudian menargetkan C.
sumber
Ketika 8087 numerik coprocessor dirancang, itu cukup umum bagi bahasa untuk melakukan semua matematika floating-point menggunakan tipe presisi tertinggi, dan hanya membulatkan hasilnya ke presisi yang lebih rendah ketika menugaskannya ke variabel presisi yang lebih rendah. Dalam standar C asli, misalnya, urutannya:
akan mempromosikan
a
danb
untukdouble
, tambahkan mereka, mempromosikanc
untukdouble
, menambah, dan kemudian menyimpan hasilnya dibulatkan menjadifloat
. Meskipun dalam banyak kasus akan lebih cepat bagi kompiler untuk menghasilkan kode yang akan melakukan operasi langsung pada tipefloat
, itu lebih mudah untuk memiliki satu set rutin floating-point yang akan beroperasi hanya pada tipedouble
, bersama dengan rutinitas untuk mengkonversi ke / darifloat
, daripada memiliki rangkaian rutin terpisah untuk menangani operasi padafloat
dandouble
. The 8087 dirancang di sekitar pendekatan aritmatika, melakukan semua operasi aritmatika menggunakan tipe floating-point 80-bit [80 bit mungkin dipilih karena:Pada banyak prosesor 16-dan 32-bit, lebih cepat bekerja dengan mantissa 64-bit dan eksponen terpisah daripada bekerja dengan nilai yang membagi byte antara mantissa dan eksponen.
Sangat sulit untuk melakukan perhitungan yang akurat dengan ketepatan penuh dari jenis numerik yang digunakan; jika seseorang mencoba misalnya menghitung sesuatu seperti log10 (x), lebih mudah dan lebih cepat untuk menghitung hasil yang akurat dalam 100ulp dari jenis 80-bit daripada menghitung hasil yang akurat dalam 1ulp dari 64-bit ketik, dan membulatkan hasil sebelumnya ke presisi 64-bit akan menghasilkan nilai 64-bit yang lebih akurat daripada yang terakhir.
Sayangnya, versi bahasa yang akan datang mengubah semantik bagaimana seharusnya tipe floating-point; sementara semantik 8087 akan sangat baik jika bahasa mendukungnya secara konsisten, jika fungsi f1 (), f2 (), dll. jenis kembali
float
, banyak penulis kompiler akan mengambil sendiri untuk membuatlong double
alias untuk jenis ganda 64-bit daripada tipe 80-bit kompiler (dan tidak menyediakan cara lain untuk membuat variabel 80-bit), dan untuk secara sewenang-wenang mengevaluasi sesuatu seperti:dengan salah satu cara berikut:
Perhatikan bahwa jika f3 dan f4 masing-masing mengembalikan nilai yang sama dengan f1 dan f2, ekspresi asli harus jelas mengembalikan nol, tetapi banyak dari ekspresi terakhir mungkin tidak. Hal ini menyebabkan orang-orang mengutuk "ketepatan ekstra" dari 8087 meskipun formulasi terakhir umumnya akan lebih unggul dari yang ketiga dan - dengan kode yang menggunakan tipe ganda diperpanjang dengan tepat - jarang akan lebih rendah.
Pada tahun-tahun berikutnya, Intel telah menanggapi tren bahasa (IMHO disayangkan) ke arah memaksa hasil antara dibulatkan ke presisi operan dengan merancang prosesor mereka yang kemudian untuk mendukung perilaku itu, dengan merugikan kode yang akan mendapat manfaat dari menggunakan yang lebih tinggi presisi pada perhitungan menengah.
sumber
## How the stack changed the processor
dan## How floating point changed the processor
) sehingga orang dapat memahami pikirannya ketika membacanya dan kecil kemungkinannya untuk berpikir bahwa Anda linglung dalam menjawab atau memposting ulang jawaban yang sama (mirip).