計算機本質(zhì)-數(shù)據(jù)運算
最初在自學《計算機體系結(jié)構(gòu)》的時候,始終沒能理解原碼、反碼、補碼到底是做什么的?直到有一天,我看到一條匯編指令"e8 db ff ff ff"。這是跳轉(zhuǎn)指令,其中"db ff ff ff"是跳轉(zhuǎn)的偏移,由于采用小端法,跳轉(zhuǎn)偏移應(yīng)該是0xffffffdb,還是不能理解呀。難道這就是體系結(jié)構(gòu)中所講述的補碼?是的,就是補碼,這串數(shù)字代表-0x25也就是-37。那究竟什么是補碼?計算機為何使用補碼來存儲數(shù)據(jù)?理解這些,就能理解在什么情況下-128*-1=-128了。后續(xù)會介紹基于整數(shù)越界獲取root權(quán)限,而-128*-1正是一個經(jīng)典的整數(shù)越界問題。
原碼是什么?
原碼就是早期用來表示數(shù)字的一種方式: 一個正數(shù),轉(zhuǎn)換為二進制位就是這個正數(shù)的原碼。負數(shù)的絕對值轉(zhuǎn)換成二進制位然后在高位補1就是這個負數(shù)的原碼
舉例說明:
int類型的 3 的原碼是 11B(B表示二進制位), 在32位機器上占四個字節(jié),那么高位補零就得:
00000000 00000000 00000000 00000011
int類型的 -3 的絕對值的二進制位就是上面的 11B 展開后高位補1就得:
10000000 00000000 00000000 00000011
但是原碼有幾個缺點,零分兩種 +0 和 -0 。很奇怪是吧!還有,在進行不同符號的加法運算或者同符號的減法運算的時候,不能直接判斷出結(jié)果的正負。你需要將兩個值的絕對值進行比較,然后進行加減操作 ,最后符號位由絕對值大的決定。于是反碼就產(chǎn)生了。
反碼是什么?
正數(shù)的反碼就是原碼,負數(shù)的反碼等于原碼除符號位以外所有的位取反
舉例說明:
int類型的 3 的反碼是
00000000 00000000 00000000 00000011
和原碼一樣沒什么可說的
int類型的 -3 的反碼是
11111111 11111111 11111111 11111100
除開符號位 所有位 取反
解決了加減運算的問題,但還是有正負零之分,然后就到補碼了
補碼是什么?
正數(shù)的補碼與原碼相同,負數(shù)的補碼為 其原碼除符號位外所有位取反(得到反碼了),然后最低位加1.
還是舉例說明:
int類型的 3 的補碼是:
00000000 00000000 00000000 00000011
int類型的 -3 的補碼是
11111111 11111111 1111111 11111101
就是其反碼加1
公眾號
