《漫談計算機組成原理》這個系列的文章共分為兩個部分。第一部分圍繞著計算機主機的外圍硬體,包括匯流排、儲存器、輸入輸出系統等,這部分的內容已經完成,感興趣的可以看看之前的文章。之前凡是涉及到CPU的內容,除了第一篇簡要的介紹過CPU的工作意外,其他文章都是預設將CPU作為一個“黑盒子”,不涉及到CPU內部的邏輯、運算等問題。而從這篇文章開始,我們將重點講述CPU的邏輯、運算、資訊處理等的相關知識點。接下來的幾篇文章都是寫計算機的運算方法的,第一篇文章我著重介紹幾個概念——原碼、反碼、補碼及移碼,後面的文章就展開看CPU究竟是如何被用來計算的。好了,話不多說,開始後半部分的第一講吧!
概述
我們當然知道,計算機只能識別0和1,也就是我們所說的機器語言。所以在程式猿進化史中出現過一種非常NB的品種——機器語言程式猿,他們的程式是寫在紙帶上面的。但是這種生物存在的時間不長(我不知道還有沒有真正意義上的機器語言程式猿),就被編譯器取代了。因為計算機只能識別0和1,所以在計算機的運算過程中,參與運算的必然只有0和1兩個數字。那麼這小小的0和1,究竟是如何完成如此複雜多變的操作的呢?
機器數與真值
在說原碼之前,我們必須提一下計算機中參與運算的兩類數(由0和1組成的“數字”),無符號數和有符號數。無符號數就是沒有符號的數,如0001,有符號的數就是有符號的數,如+10001、-0010等。此外,**無符號數和有符號數的表示範圍並不相同,無符號數表示的範圍是0 ~ 65535,即0~ 2^16^ -1;有符號數的表示範圍是-32768 ~ +32767,雖然範圍不同,但是表示的資料都是2^16^個。**除此之外,無符號數和有符號數的另一個重要的不同點就是在暫存器中的存放方式:無符號數可以直接存放在暫存器中,但是有符號數是有符號位的,所以需要連同符號位一起儲存在暫存器中。+和-是兩種狀態,0和1也是兩種狀態,所以+對應0,-對應1,儲存到暫存器中就很簡單了。 【注】原碼、反碼、補碼、移碼均屬於有符號數。
原碼
原碼可以說是計算機中最簡單的、也是一種最基本的資料表達形式,比如-0001,符號位是-,所以第一位就是1,而真值位就是-0001的絕對值,即0001,所以-0001的原碼就是10001。 因為原碼可能是整數的原碼,也有可能是小數的原碼,這就造成了一個問題——**該如何表示原碼中的小數點,即便是整數也有小數點。**整數的原碼很好表示,符號位和真值位之間由逗號分割,小數位在真值後,可以不寫出來,即表示為1,0001。至於小數的原碼,小數點就表示為小數點。如-0.11001,表示為1.11001。 原碼錶示方式的總結 教科書式的表示方式是在是讓人眼花繚亂(個人認為),我在這裡直接用文字表述原碼的表示方式。
- 整數的原碼錶示:符號位如果是+,則直接在真值的絕對值前加上符號位0和“,”;符號位如果是-,則直接在真值的絕對值前加1和“,”
- 小數的原碼錶示:符號位如果是+,則直接在真值的絕對值前加上符號位0和“.”;符號位如果是-,則直接在真值的絕對值前加1和“.”
補碼
你可能沒有聽過補碼,但是肯定聽過補角。如果說兩個角互補,那麼這兩個角的角度相加肯定是180度的。如下圖所示:
角A:120°,角B:60°,兩角之和為180°。這就是補角的概念。 但是補碼和補角略有不同。補碼是一種有模的資料,是有正負的。如:當前鐘錶表示時間為6:00,想要讓時間表示為12:00,我既可以讓時針逆時針調整6個小時,也可以順時針調整6個小時,如果順時針記為+,逆時針記為-,則+6和-6所達到的效果是一致的。我們就稱+6和-6是以12為模的補數。所以,我們可以使用+6來代替-6,也可以用+9來代替-3(同樣是12為模)。 補碼也是同樣的道理,就是用一個正數來替代一個負數。為啥要這樣做呢?因為這可以減少一種運算,就是減法運算。這樣就可以使計算機的運算,不論加減,都能當做加來運算。但是乘除不能轉換。 關於補碼的表示,規則如下:
- 正數的補碼是其本身(實際上,正數的補碼、原碼、反碼都是其本身)
- 負數的補碼:運算方式--->符號位保持不變,其餘為取反,末位+1 如:-100100的補碼為:除符號位各位取反1,011011;末位+1:1,011011+1 = 1,011100.所以1,011100就是最終的結果
反碼
反碼存在的意義:在原碼和補碼的互相轉換過程中起到一個過渡的作用。 反碼的表示更加簡單:
- 正數的反碼錶示:其本身
- 負數的反碼錶示:除符號位不變,其餘位各位取反(大家可以找個數字嘗試一下)
移碼
移碼很有用,具體作用就是比較大小。 下面兩個數:1,0001和0,0001,判斷大小。乍一看,好像是1,0001>0,0001。但是你別忘了,1,0001可是負數…… 這個問題就非常好玩了,這種簡單的數對於人其實還好判斷一些,但是對於計算機,他並不能像人一樣思考。 如果我們這樣做:將1,0001和0,0001都加上一個0,1111,最終的結果都成為符號相同的數了,肯定是非常好比較的了。 所以,[x]~移~ = 2^n^ + x(x是真值,n是整數x的位數,小數沒有移碼) 這樣,我們就能很好的判斷資料的大小了。 如果你親自計算了,你會發現:正整數的移碼和補碼只相差了一個符號位。
總結
這篇文章是後續文章的基石,相對簡單。大家只需要記住資料的原碼、反碼、補碼的運算即可,移碼屬於瞭解範疇。 如果你喜歡我的文章,歡迎關注微信公眾號:最高許可權位元流。