Nomor yang ditandatangani dan tidak ditandatangani

17

Bagaimana ALU dalam mikroprosesor membedakan antara angka yang ditandatangani, -7 yang dilambangkan dengan 1111 dan angka 15 yang tidak ditandatangani, juga dilambangkan dengan 1111?

noorav
sumber
3
Lihat jawaban pertanyaan terkait: cs.stackexchange.com/a/30047/28999 . By the way, ditandatangani -7 tidak direpresentasikan sebagai 1111. Itu -1. Kemudian mis. 1111 - 0001 = 1110 dalam kasus yang ditandatangani dan tidak ditandatangani (-2 vs 14)
Albert Hendriks
2
@AlbertHendriks Dalam keadilan, beberapa komputer lama memang menggunakan "representasi sign-magnitude" (satu bit tanda dan bit magnitudo), dan kami masih menggunakan gaya itu untuk misalnya IEEE float. Mereka hanya canggung dan sulit untuk bekerja dibandingkan dengan dua-pelengkap. n-1
Draconis
1
Perbedaan utama adalah bagaimana perilaku operator Greater / lessThan, dan apakah shift kanan mengisi dengan bit tertinggi. Ketika Anda benar-benar berkembang biak dan membelah, hasilnya sama.
Rob
2
@Rob Itu tidak sepenuhnya benar. Penambahan, pengurangan, dan perkalian semua sama antara komplemen unsigned dan dua-sama - dengan asumsi input dan output Anda adalah ukuran yang sama. Division tidak sama 6/2 adalah 3, tetapi -2/2 adalah -1. Dan banyak CPU memiliki instruksi perkalian di mana kedua input berukuran sama, tetapi outputnya dua kali lebih besar, dalam hal ini unsigned dan dua komplemen tidak sama.
kasperd

Jawaban:

14

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, SUBmenafsirkan pola bit sebagai semacam nomor, sedangkan petunjuk logis seperti AND, OR, XORmenafsirkannya 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.

Jörg W Mittag
sumber
Perhatikan bahwa bytecode Java juga dianggap sebagai ISA. Dan itu cukup peduli tentang tipe data ...
John Dvorak
Bytecode Java tidak mengurutkan sebagai ISA, dalam arti bahwa itu telah diimplementasikan dalam silikon. Namun, pengecekan tipe dasar dari jenis ini adalah pengecekan yang dilakukan oleh classloader, sehingga tipe-tipe tersebut sebagian besar dapat diabaikan pada saat run-time. Dan tentu saja bytecode Java tidak memiliki tipe unsigned di tempat pertama.
Nama samaran
@ Nama samaran: Yah, secara teknis, memang ada char, yang merupakan tipe 16-bit unsigned. Tentu saja, masih belum ada instruksi aritmatika yang tidak ditandatangani di bytecode Java, karena charnilai apa pun secara otomatis dipromosikan ke int(32-bit ditandatangani) untuk aritmatika.
Ilmari Karonen
42

Versi singkat: tidak tahu. Tidak ada cara untuk mengatakannya.

Jika 1111mewakili -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 SADDdan UADDopcode, dan jika Anda memilih yang salah, Anda mendapatkan hasil yang tidak masuk akal.

Namun, lebih sering 1111mewakili -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.

Draconis
sumber
Ah, mengerti. Terima kasih untuk ini :)
noorav
10
Dalam representasi komplemen dua, tiga operasi aritmatika adalah sign-agnostik: penjumlahan, pengurangan dan perkalian (dengan produk dengan panjang yang sama dengan operan). Hanya divisi yang harus ditangani secara berbeda untuk operan yang ditandatangani.
Ruslan
4
Ada juga perbandingan: < <= >= >berbeda untuk operan yang ditandatangani vs yang tidak ditandatangani sedangkan ==dan itu !=adalah agnostik-signness.
Daniel Schepler
Perkalian sering kali memiliki varietas bertanda dan tidak bertanda tangan: 0xFFFFFFFF * 0xFFFFFFFF adalah 0xFFFFFFFE00000001 jika tidak ditandatangani dan 0x0000000000000001 jika ditandatangani. Prosesor seperti Intel mengembalikan hasilnya dalam 2 register, dan register teratas memang berbeda untuk yang ditandatangani dan yang tidak ditandatangani. Daftar terbawah adalah 1 di kedua situasi.
Rudy Velthuis
9

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 CMPdengan 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.

Davislor
sumber
1
Bahkan perkalian adalah sama untuk bilangan bulat bertanda tangan dan ditandatangani (komplemen dua), selama Anda tidak perlu hasilnya memiliki lebih banyak bit daripada input . Jika Anda melakukan sesuatu seperti 8 × 8 → 16 bit (atau 16 × 16 → 32 bit, dll.), Namun, Anda harus menandatangani perpanjangan input (atau hasil antara) .
Ilmari Karonen
@IlmariKaronen Ini benar; ARM A32 / A64 adalah set instruksi yang memiliki banyak bentuk instruksi multiply, termasuk sign-agnostic multiply-add yang hanya menulis bit orde rendah, tetapi juga smulhdan umulhyang 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.
Davislor
6

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.

Jay Speidell
sumber
Tidak ada yang namanya charlevel hardware. Mungkin sekali waktu, kembali pada zaman teleprinter mekanik. Tapi hari ini, charadalah 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").
Solomon Slow
3

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 divuntuk melakukan divisi yang tidak ditandatangani dan instruksi yang dinamai idivuntuk 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.

Martin Rosenau
sumber