Bagaimana ALU dalam mikroprosesor membedakan antara angka yang ditandatangani, -7 yang dilambangkan dengan 1111 dan angka 15 yang tidak ditandatangani, juga dilambangkan dengan 1111?
Bagaimana ALU dalam mikroprosesor membedakan antara angka yang ditandatangani, -7 yang dilambangkan dengan 1111 dan angka 15 yang tidak ditandatangani, juga dilambangkan dengan 1111?
Jawaban:
Jawaban singkat dan sederhana adalah: tidak. Tidak ada CPU ISA arus utama modern yang berfungsi seperti yang Anda pikirkan.
Untuk CPU, itu hanya sedikit pola. Terserah Anda, programmer, untuk melacak apa arti pola bit itu.
Secara umum, ISA tidak membedakan antara tipe data yang berbeda, ketika datang ke penyimpanan. (Mengabaikan register tujuan khusus seperti register mengambang dalam FPU.) Ini hanya pola bit yang tidak berarti bagi CPU. Namun, SPA memang memiliki berbagai jenis instruksi yang dapat menginterpretasikan pola bit dengan cara yang berbeda. Misalnya, petunjuk aritmatika seperti MUL
, DIV
, ADD
, SUB
menafsirkan pola bit sebagai semacam nomor, sedangkan petunjuk logis seperti AND
, OR
, XOR
menafsirkannya sebagai array boolean. Jadi, terserah, programmer, (atau penulis interpreter atau kompiler jika Anda menggunakan bahasa tingkat yang lebih tinggi) untuk memilih instruksi yang benar.
Mungkin ada instruksi terpisah untuk nomor yang ditandatangani vs. yang tidak ditandatangani, misalnya. Beberapa ISA juga memiliki instruksi untuk aritmatika dengan desimal berkode biner.
Namun, perhatikan bahwa saya menulis "ISA arus utama modern" di atas. Sebenarnya ada SPA non-mainstream atau bersejarah yang bekerja secara berbeda. Sebagai contoh, baik ISA CISC 48-bit asli dari IBM AS / 400 maupun RISC ISA 64-bit berbasis sistem saat ini yang disebut IBM i, membedakan antara pointer dan nilai-nilai lainnya. Pointer selalu ditandai, dan mereka memasukkan informasi jenis dan manajemen hak. CPU tahu apakah suatu nilai adalah sebuah pointer atau tidak, dan hanya kernel i / OS istimewa yang diizinkan untuk memanipulasi pointer secara bebas. Aplikasi pengguna hanya dapat memanipulasi pointer yang mereka miliki untuk menunjuk pada memori yang mereka miliki menggunakan sejumlah kecil instruksi yang aman.
Ada juga beberapa desain ISA bersejarah yang mencakup setidaknya beberapa bentuk terbatas jenis kesadaran.
char
, yang merupakan tipe 16-bit unsigned. Tentu saja, masih belum ada instruksi aritmatika yang tidak ditandatangani di bytecode Java, karena char
nilai apa pun secara otomatis dipromosikan ke int
(32-bit ditandatangani) untuk aritmatika.
Versi singkat: tidak tahu. Tidak ada cara untuk mengatakannya.
Jika 1111
mewakili -7, maka Anda memiliki representasi sign-magnitude , di mana bit pertama adalah tanda dan sisanya adalah magnitude. Dalam hal ini, aritmatika agak rumit, karena add yang tidak ditandatangani dan add yang ditandatangani menggunakan logika yang berbeda. Jadi, Anda mungkin memiliki SADD
dan UADD
opcode, dan jika Anda memilih yang salah, Anda mendapatkan hasil yang tidak masuk akal.
Namun, lebih sering 1111
mewakili -1, dalam apa yang disebut representasi dua-pelengkap . Dalam hal ini, ALU sama sekali tidak peduli jika nomornya ditandatangani atau tidak! Sebagai contoh, mari kita ambil operasi 1110 + 0001
. Dalam aritmatika yang ditandatangani, ini berarti "-2 + 1", dan hasilnya harus -1 ( 1111
). Dalam aritmatika yang tidak ditandatangani, ini berarti "14 + 1", dan hasilnya harus 15 ( 1111
). Jadi ALU tidak tahu apakah Anda ingin hasil yang ditandatangani atau tidak, dan itu tidak peduli. Itu hanya melakukan penambahan seolah-olah itu tidak ditandatangani, dan jika Anda ingin memperlakukannya sebagai integer yang ditandatangani sesudahnya, itu terserah Anda.
EDIT: Seperti yang tepat ditunjukkan oleh Ruslan dan Daniel Schepler dalam komentar, beberapa operan masih perlu versi yang ditandatangani dan tidak ditandatangani secara terpisah, bahkan pada mesin dua pelengkap. Penambahan, pengurangan, perkalian, kesetaraan, dan semua itu berfungsi dengan baik tanpa mengetahui apakah angka-angka tersebut ditandatangani atau tidak. Tetapi pembagian dan perbandingan yang lebih besar dari / kurang dari harus memiliki versi terpisah.
EDIT EDIT: Ada beberapa representasi lain juga, seperti pelengkap seseorang , tetapi ini pada dasarnya tidak pernah digunakan lagi sehingga Anda tidak perlu khawatir tentang mereka.
<
<=
>=
>
berbeda untuk operan yang ditandatangani vs yang tidak ditandatangani sedangkan ==
dan itu !=
adalah agnostik-signness.
Salah satu keuntungan besar matematika dua-pelengkap, yang digunakan semua arsitektur modern, adalah bahwa instruksi penambahan dan pengurangan persis sama untuk operan yang ditandatangani dan yang tidak ditandatangani.
Banyak CPU bahkan tidak memiliki instruksi multiply, divide atau modulus. Jika ya, mereka harus memiliki bentuk instruksi yang ditandatangani dan tidak ditandatangani yang terpisah, dan kompiler (atau programmer bahasa assembly) memilih yang sesuai.
CPU juga umumnya memiliki instruksi berbeda untuk perbandingan yang ditandatangani atau tidak ditandatangani. Misalnya, x86 dapat mengikuti a CMP
dengan JL
(Lompat jika Kurang dari) jika perbandingan harus ditandatangani, atau JB
(Lompat jika Di Bawah) jika perbandingan tersebut harus ditandatangani. Sekali lagi, kompiler atau programmer akan memilih instruksi yang tepat untuk tipe data.
Beberapa instruksi lain sering kali masuk dalam varian yang ditandatangani dan tidak ditandatangani, seperti penggeseran kanan atau pemuatan nilai ke dalam register yang lebih luas, dengan atau tanpa ekstensi masuk.
smulh
dan umulh
yang mengembalikan hanya bit atas dari perkalian dan instruksi yang ditandatangani dan tidak ditandatangani yang kembalikan hasilnya dalam register dua kali lebih lebar dari operan sumber.
Tidak. Prosesor bergantung pada set instruksi untuk memberi tahu jenis data apa yang dilihatnya dan di mana untuk mengirimnya. Tidak ada apapun tentang 1s dan 0s dalam operan itu sendiri yang secara inheren dapat memberi sinyal kepada ALU apakah data itu char, float, int, int int, dll. Jika 1111 itu akan ke sirkuit listrik yang mengharapkan komplemen 2s, itu akan untuk ditafsirkan sebagai pelengkap 2s.
char
level hardware. Mungkin sekali waktu, kembali pada zaman teleprinter mekanik. Tapi hari ini, char
adalah hanya nomor sejauh hardware yang bersangkutan. Alasan mengapa angka-angka yang berbeda sesuai dengan bentuk huruf yang berbeda di layar Anda adalah bahwa angka-angka itu digunakan untuk memilih bitmap yang berbeda atau rutinitas gambar yang berbeda dari tabel besar (yaitu, dari "font").
Saya ingin memberi tambahan pada jawaban yang sudah dibuat:
Dalam sebagian besar jawaban lain, dicatat bahwa dalam aritmatika berpasangan dua, hasilnya sama untuk bilangan yang ditandatangani dan tidak bertanda:
-2 + 1 = -1 1110 + 0001 = 1111
14 + 1 = 15 1110 + 0001 = 1111
Namun , ada beberapa pengecualian:
Division:
-2 / 2 = -1 1110 / 0010 = 1111
14 / 2 = 7 1110 / 0010 = 0111
Comparison:
-2 < 2 = TRUE 1110 < 0010 = TRUE
14 < 2 = FALSE 1110 < 0010 = FALSE
"Typical" (*) multiplication:
-2 * 2 = -4 1110 * 0010 = 11111100
14 * 2 = 28 1110 * 0010 = 00011100
(*) Pada banyak CPU, hasil dari perkalian dua angka n-bit adalah (2 * n) lebar bit.
Untuk operasi seperti itu CPU memiliki instruksi yang berbeda untuk aritmatika yang ditandatangani dan tidak ditandatangani.
Ini berarti programmer (atau kompiler) harus menggunakan instruksi lain untuk aritmatika yang ditandatangani dan tidak ditandatangani.
CPU x86 misalnya memiliki instruksi yang dinamai div
untuk melakukan divisi yang tidak ditandatangani dan instruksi yang dinamai idiv
untuk melakukan divisi yang ditandatangani.
Ada juga berbagai instruksi "kondisional" (lompatan kondisional, set-bit-on-kondisi) serta instruksi multiplikasi untuk aritmatika yang ditandatangani dan tidak ditandatangani.