看板 b99902HW 關於我們 聯絡資訊
二的補數、Offset 與 Extender by bill8124 Outline: 複習一下二的補數 解釋 $gp Offset 解釋 Extender 的差別 ---- ◎ 二的補數 範例: 124 = 0000 0001 0010 0100 先取一的補數 -> 1111 1110 1101 1011 (0變1、1變0) 加 1 變成二的補數 -> 1111 1110 1101 1100 這個數字以 signed integer 解讀就是 -124。 反過來看,如果我們對 -124 做二的補數, -124 = 1111 1110 1101 1100 -> 0000 0001 0010 0011 -> 0000 0001 0010 0100 剛好就會得到原本的 124。 ---- ◎ 解釋 $gp Offset 這個段落其實可以用一句話說完: 「寫成 unsigned,讀作 signed。」 當 $gp = 1000 8000 ,而我們想要存取的位置是 1000 0000 那我們需要的 offset 就是 -8000 一般而言,人類看到負數不知道如何用 bit 表示 所以要知道 -8000 怎麼用 bit 表示,就要從 +8000 轉成 -8000 8000 = 1000 0000 0000 0000 -> 0111 1111 1111 1111 -> 1000 0000 0000 0000 轉成 -8000 跟原本一樣,這是怎麼回事呢? 計程的時候曾經教到,signed int 的表示範圍是 2147483647 = 7FFFFFFF = 0111 1111 1111 1111 1111 1111 1111 1111 (32 bits) 到 -2147483648 = -80000000 = 1000 0000 0000 0000 0000 0000 0000 0000 7FFFFFFF + 1 = 1000 0000 0000 0000 0000 0000 0000 0000 0000 如果用 signed integer 的角度來看,這個數就是 -80000000 (對 signed 來說,看到第一個 bit 是 1 就是負數) 從 unsigned integer 的角度來看,這個數就是 +80000000 (對 unsigned 來說,這個 1 是數字的一部份) 所以 lw $a0, 8000($gp) 其實應該寫成 lw $a0, -8000($gp) 因為,這裡的 Offset: 8000 應該要看成是 signed integer 的 -8000 另外一個例子。$gp 不變,資料放在 1000 0020 需要 Offset = -7FE0 (1000 8000 - 7FE0 = 1000 0020) 7FE0 = 0111 1111 1110 0000 -> 1000 0000 0001 1111 -> 1000 0000 0010 0000 = -7FE0 (signed) = 8020 (unsigned) 這樣就了解為什麼要寫成 sw $s0, 8020($gp) 了吧! 我不知道為什麼要故意把 signed 的數表示成 unsigned 的樣子, 但總而言之,看到 >= 8000 的 16 bit 數字,就是負數了! ---- ◎ 解釋 Extender Extender 有兩種: Zero extender 和 Sign extender Zero extender 就是不管拿到什麼數字,前面都補零 Sign extender 是讓 16 bit 數字變成 32 bit,但數值不變。 舉例來說 70C0 = 0111 0000 1100 0000 zero_ext -> 0000 0000 0000 0000 0111 0000 1100 0000 = 7412 sign_ext -> 0000 0000 0000 0000 0111 0000 1100 0000 = 7412 -3A00 = 1100 0110 0000 0000 (這裡請自己算出來XD) zero_ext -> 0000 0000 0000 0000 1100 0110 0000 0000 = C600 sign_ext -> 1111 1111 1111 1111 1100 0110 0000 0000 = -3A00 對 -3A00 的 sign_ext 取二的補數會得到 3A00,各位可以自己試試看。 簡單的記法是:把第 1 個 bit 重複往前填滿。(參考上面範例) 順道一提,通常做 Zero_ext 的時候,原本的數字都會以 unsigned 的形式來用。 以上面的例子來說,這個數字應該看作 C600 而非 -3A00。 CPU 中的 Extender 有個 ExtOp 的 flag 0 代表 Zero_ext,1 是 Sign_ext(從 instuction 的 flag table 可以看出來) ---- 希望這篇文有讓不太懂這一部份的人,可以完全瞭解。 另外 ExtOp 的部分,今天計結老師應該是漏講了。 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 114.45.207.217 ※ 編輯: bill8124 來自: 114.45.207.217 (10/24 22:29) ※ 編輯: bill8124 來自: 114.45.207.217 (10/24 22:31) ※ 編輯: bill8124 來自: 114.45.207.217 (10/24 22:31)
allen0326200:助教用心推! 10/24 22:45
allen0326200:sorry沒看原po的ID 以為是TA 謝囉 10/24 22:48
ga800360:推! 10/25 01:39
maill6802:推 10/25 11:28
OppOops:推!! 10/25 18:39
han960691:push! 10/25 23:25