- 單片微型計算機原理及應用
- 姜志海 劉連鑫 王蕾編著
- 7571字
- 2019-01-09 14:52:23
1.4 計算機中的數制和編碼基礎
計算機的工作過程就是對數據進行處理。計算機是一個典型的數字化設備,它只能識別0和1,所有的計算機都是以二進制數的形式進行算術運算和邏輯操作的。
1.4.1 計算機中的數制及轉換
1.計算機中的數制
計算機最早是作為一種計算工具出現的,所以最基本的功能是對數進行加工和處理。數在機器中是以器件的物理狀態來表示的。一個具有兩種不同的穩定狀態且能相互轉換的器件可以用來表示1位(bit)二進制數。二進制數有運算簡單、便于物理實現、節省設備等優點,所以目前在計算機中的數幾乎全部采用二進制表示。但是二進制數書寫起來太長,且不便于閱讀和記憶,又加上目前大部分微型計算機是8位、16位或32位的,都是4的整數倍,而4位二進制數即是1位十六進制數,所以微型計算機中的二進制數都采用十六進制數來表示,日常生活中我們主要使用十進制數。因此在使用微型計算機時常用的計數制有二進制數、十六進制數、十進制數3種。
(1)十進制數(Decimal)
以10為基數的計數制稱為十進制計數制。十進制數有如下兩個特點:
① 有0~9共10個不同的數碼。
② 在加法中采用逢10進1的原則。
人們在實際生活中常用的是十進制數。
(2)二進制數(Binary)
以2為基數的計數制稱為二進制計數制。二進制數有如下兩個特點:
① 有0、1共2個不同的數碼。
② 在加法中采用逢2進1的原則。
計算機中使用的是二進制數。
(3)十六進制數(Hexadecimal)
十六進制是人們學習和研究計算機中二進制數的一種工具,它是隨著計算機的發展而廣泛應用的。十六進制數有如下三個特點:
① 有0~9、A、B、C、D、E、F共16個不同的數碼。
② 在加法中采用逢16進1的原則。
③ 在書寫一個十六進制數時,如果該數據的高位為A~F,則在高位的前面加“0”,如0AH、0EFH、0FEABH、0CB98H等。
十進制數、二進制數和十六進制數之間的關系如表1-4所示。
表1-4 十進制、二進制數及十六進制數對照表

為了區別十進制數、二進制數及十六進制數三種數制,可以在數的后面加1個字母。規定B(binary)表示二進制數,D(decimal)表示十進制數,H(hexadecimal)表示十六進制數,其中十進制數后面的字母D可以省略。
2.各種數制之間的轉換
人們習慣的是十進制,計算機采用的是二進制,而二進制的表示多采用十六進制,因此必須掌握數制的轉換問題。
(1)二進制數和十六進制數間的相互轉換
根據表1-4所示的對應關系即可實現它們之間的轉換。
二進制整數轉換為十六進制數,其方法是從右(最低位)向左將二進制數分組:每4位為1組,最后一組若不足4位則在其左邊添加0,每組用1位十六進制數表示。如:
1111111000111B=1FC7H
十六進制數轉換為二進制數,只需用4位二進制數代替1位十六進制數即可。如:
3AB9H=0011101010111001B
(2)十六進制數和十進制數間的相互轉換
十六進制數轉換為十進制數十分簡單,只需將十六進制數按權展開即可。如:

十進制整數轉換為十六進制數可用除16取余數法,即用16不斷地去除待轉換的十進制數,直到商等于零為止。將所得的各次余數,依倒序排列,即可得到所轉換的十六進制數。例如,將38947轉換為十六進制數,即38947=9823H。其方法及算式如圖1-15所示。

圖1-15 將38947轉換為十六進制數
一個十進制小數轉換成十六進制小數時,可采用乘16取整的方法進行。例如,將十進制數0.7875轉換為十六進制數,轉換結果為0.7875D=0.C99H。其方法和算式如圖1-16所示。

圖1-16 將0.7875轉換為十六進制數
注意小數轉換不一定能算盡,只需算到一定精度的位數即可,因此可能會產生一些誤差,但當位數較多時,這個誤差就很小了。
如果一個十進制數既有整數部分又有小數部分,可將整數部分和小數部分分別進行十六進制數的等值轉換,然后合并即可得到結果。
1.4.2 帶符號數的表示
1.機器數與真值
計算機在處理實際問題時所遇到的數據通常是帶符號數。在計算機中,對于帶符號數來說,一般用最高位表示數的正、負。對于正數,最高位規定為“0”,對于負數,最高位規定為“1”,例如:
56H可以表示01010110B(對于8位二進制數來說,D7位表示數的正負,D6~D0表示數的絕對值),-56H可以表示11010110B。
0256H可以表示0000 001001010110B(對于16位二進制數來說,D15位表示數的正負,D14~D0表示數的絕對值),-0256H可以表示1000 001001010110B。
在計算機中,用二進制數表示有符號數,用最高位表示符號,其余的為數值位,這樣一組連同符號也編碼化的二進制數稱為機器數,機器數所代表的數值大小稱為機器數的真值。
【例1-2】 寫出X1=+42,X2=-42,X3=+91,X4=-91的真值和機器數。
設機器的字長為8位,則有:
[X1]真=+101010B=+42,X1的機器數為00101010B。
[X2]真=-101010B=-42,X2的機器數為10101010B。
[X3]真=+1011011B=+91,X3的機器數為01011011B。
[X4]真=-1011011B=-91,X4的機器數為11011011B。
2.機器數的原碼、反碼、補碼
數據在計算機內采用符號數字化處理后,機器可表示并識別帶符號的數據。為了改進運算方法、簡化控制電路,人們研究出多種有符號數的編碼形式,最常用的有三種方法,即原碼、反碼、補碼表示法。
數X的原碼記為[X]原,反碼記為[X]反,補碼記為[X]補。
(1)原碼表示法
對于帶符號數來說,用最高位表示數的正負,其余各位表示數的絕對值,這種表示方法稱為原碼表示法,即僅將符號位數字化表示為0或1,數的絕對值與符號一起編碼,或者稱為“符號-絕對值”的編碼。
原碼表示的特點如下:
① 最高位為符號位,正數為0,負數為1。
② 8位二進制原碼表示數的范圍是-127~+127,十六位二進制原碼表示數的范圍是-32767~+32767。
③ 0的原碼有兩種表示方法,即+0和-0,設字長為8位:
[+0]原=00000000B
[-0]原=10000000B
采用原碼表示時,編碼簡單直觀,但也帶來一些麻煩,一是引起機器中“零”的表示不唯一,零有二義性,給機器判零帶來麻煩,必須在設計時約定好機器采用正零或負零;二是不便于進行加減運算。用原碼進行四則運算時,符號位需單獨處理,而且原碼加減運算規則復雜。例如對有符號數的加法規則為:若兩個數同號,兩數絕對值相加,結果冠以共同的符號;若兩個數異號,兩數絕對值相減,結果冠以絕對值大的數值的符號。而減法又有一套規則。故原碼表示法一般不用于加減運算。
(2)反碼表示法
正數的反碼與原碼相同,如[56H]反=[56H]原=01010110B。
負數的反碼等于原碼除符號位外,其余各位按位取反。因此,求-56H反碼的過程如下:
對應正數56H的原碼為0101 0110B;按位求反后為1010 1001B,即-56H的反碼為10101001B。
反碼的特點:
① 反碼表示法中,最高位仍為符號位,正數為0,負數為1。
② “0”有兩種表示方法:當字長是8位時,[+0]反=00000000B,[-0]反=11111111B。
③ 8位二進制反碼表示數的范圍是-127~+127,16位二進制反碼表示數的范圍是-32767~+32767。
④ 正數的反碼與原碼相同,負數的反碼符號位為1,其數值部分按位取反。
(3)補碼
在計算機內,帶符號數并不是用反碼表示的,而是用補碼表示的,引入“原碼”、“反碼”的目的只是為了方便理解“補碼”的概念而已。
不用原碼表示的原因是:用原碼表示時,“0”的原碼并不唯一,0的原碼可以表示為00000000B(即+0),也可以表示為10000000B(即-0),這會造成混亂;再就是用原碼表示時,減法并不能轉化為加法運算,反碼也存在類似的問題。在計算機中,帶符號數用補碼表示后,減法可以轉化為加法運算,例如:

① 100H是8位二進制能表示的最大數,加上100H后,對計算結果沒有影響,原因是8位二進制無法存放100H中的“1”,即D8位。
② 由于8位二進制不能存放D8位,結果133H中最高位“1”自然丟失。
顯然,56H-23H的結果與56H+0DDH的結果相同,即引入補碼后,減法可以用加法來完成。可見,在8位二進制中,23H與0DDH互為補碼。
下面以鐘表為例進一步理解補碼的問題。對一個現實生活中的鐘表來說,現在時鐘指在11時,需要調校到6時,則可以順時針撥11+7=12+6=6;也可以逆時針撥11-5=6。這里,自動丟失的循環最大值(12)稱為模,即當模是12時,11-5=12+7=6,其中7稱為-5的補碼,即
(-5)補=12-|-5|=7
依次類推,對于n位(如8位)二進制而言,其模為2n(28),則(負數)補=2n-|負數|。
補碼的定義如下:
正數的補碼與反碼、原碼相同;負數的補碼等于它的反碼加1。
例如,+23H的補碼:00100011B;-23H的補碼:-23的原碼為10100011B,-23H的反碼為11011100B;反碼加1后為11011101B,即-23H的補碼為11011101B(相當于無符號數的0DDH)。
可見,用補碼表示時,若最高位為0,表示該數為正數,數值部分就是真值;若最高位為1,則表示該數為負數,數值部分并不是它的真值,必須再求補后,才得到該數的絕對值,如上例中的-23H的補碼為11011101B,按位取反后為00100010B,加1后為00100011B,即23H。
補碼的特點:
① 補碼表示中,最高位仍為符號位,正數為0,負數為1。
② 0僅有一種表示方法,即[+0]補=[-0]補。
③ 8位二進制補碼表示數的范圍是-128~+127,16位二進制補碼表示數的范圍是-32768~+32767;對于同一個數,作為8位二進制數的補碼和作為16位二進制數的補碼不同,這一點要特別注意。
注意:對于8位二進制數10000000B,若為補碼表示為[-128]補,若為原碼表示[-0]原,若為反碼表示為[-127]反。
關于補碼,注意以下幾點:
① 在微型計算機中所有帶符號的數都是用補碼表示的。一個數據是帶符號的數還是不帶符號的數,事先是已知的。
② 當求補碼的真值時,例如8位的補碼,若最高位為0時,其余7位即為此數的二進制數值。但當最高位為1(即負數)時,需要把其余7位求反以后最低位加1,才是它的二進制數的絕對值。例如:
[X]補=10010100B
[X]真=-(1101011)=-1101100B=-108D
③ 采用補碼的目的在于可用加法運算代替減法運算,從而可以簡化硬件結構,降低成本。
【例1-3】 計算64-10=?
【解】
64-10=54,可用[X]補=[64]補-[+10]補進行減法運算。而[64]補=01000000B,[+10]補=00001010B。運算如圖1-17所示。

圖1-17 補碼相減算式
該運算也可寫成下式:
64-10=64+(-10)=54
可用[X]補=[64]補+[-10]補進行加法運算。其中[-10] 補=11110110B,運算如圖1-18所示。

圖1-18 補碼相加算式
故[X]補=00110110B。由以上運算可知,補碼相加的結果與補碼相減的結果是一致的。因此,可用補碼相加代替補碼相減的運算。
④ 補碼運算時符號位不需要單獨處理,符號位與數值部分一起參加運算,在不發生溢出的情況下,運算結果(包括符號位)是正確的。
8位二進制數用來表示有符號數、原碼、反碼和補碼,如表1-5所示。
表1-5 原碼、反碼和補碼表

從表1-5 可以看出,8位二進制數,無符號數表示范圍是0~255,有符號數原碼表示范圍中-127~+127,反碼表示范圍是-127~+127,補碼表示范圍是-128~+127。
3.帶符號數溢出及其判斷方法
(1)什么是溢出
在選定了運算字長和數的表示方法之后,如果運算的結果超出了計算機所能表示的數據范圍,則稱這種情況為廣義上的溢出。
從嚴格意義上講,廣義上的溢出既包括帶符號數的溢出,也包括無符號數的溢出,但下面把帶符號數的數據結果超出表示范圍稱為溢出,而把無符號數的數據結果超出表示范圍稱為進位。因為對于無符號數的加減運算,無論運算的結果是否超出數據表示范圍(在計算機字長范圍內),運算結果都是正確的。而對于帶符號數的加減運算,如果沒有溢出,則運算結果是正確的,而如果產生溢出,則運算結果是錯誤的。
對于8位字長的微處理器,其原碼、反碼和補碼表示的范圍分別為
原碼 -127~+127(0FFH~7FH)
反碼 -127~+127(80H~7FH)
補碼 -128~+127(80H~7FH)
當8位帶符號數的運算結果超過以上范圍時,就會產生溢出。
對于16位字長的微處理器,其原碼、反碼和補碼表示的范圍分別為
原碼 -32767~+32767(0FFFFH~7FFFH)
反碼 -32767~+32767(8000H~7FFFH)
補碼 -32768~+32767(8000H~7FFFH)
當16位帶符號數的運算結果超過以上范圍時,就會產生溢出。
【例1-4】 已知X=01000000B,Y=01000001B,進行補碼的加法運算。
【解】
[X]補=01000000B=+64
[Y]補=01000001B=+65
[X]補+ [Y]補=10000001B=-127
兩個正數相加,其結果應該是+129,但運算結果為-127,這顯然是錯誤的,其原因在于和數+129 > +127,超出了8位補碼所能表示的最大值,使數值部分占據了符號位的位置,產生了溢出錯誤。
(2)判斷溢出的方法
溢出只能出現在兩個同符號數相加或兩個異符號數相減的情況下。利用雙進位方法判斷有無溢出是一種常用的方法,其規則如下:在兩個同符號數相加或兩個異符號數相減時,如果次高位向最高位有進位(或借位),而最高位向前無進位(或借位),則結果發生溢出;反之,如果次高位向最高位無進位(或借位),而最高位向前有進位(或借位),則結果也發生溢出。
這種方法是利用最高位和次高位的進位/借位狀態進行“異或”來判斷的。對8位二進制數來說,如果溢出記為OF,最高位和次高位的進位/借位狀態分別記為C7和C6,則OF=C7⊕C6,當OF=1時表示有溢出,當OF=0時表示無溢出。
在微機中,可用多字節表示更大的數,避免產生溢出錯誤。
1.4.3 定點數和浮點數
計算機中運算的數有整數,也有小數。通常有兩種規定:一種是規定小數點的位置固定不變,這時的機器數稱為定點數;另一種是小數點的位置可以浮動,這時的機器數稱為浮點數。微型計算機中常使用定點數。
1.定點數
所謂定點法,是指小數點在數中的位置是固定不變的,以定點法表示的實數稱為定點數。根據小數點位置的固定方法不同,又可分為定點整數和定點小數表示法。前面介紹的整數均為定點整數,可以認為小數點固定在數的最低位之后。
如果小數點隱含固定在整個數值的最右端,符號位右邊所有的位數表示的是一個整數,即為定點整數。例如,對于16位機,如果符號位占一位,數值部分占15位,于是機器數0111111111111111 的等效十進制數為+32767,其符號位、數值部分、小數點的位置示意如圖1-19所示。

圖1-19 定點整數的符號位、數值部分和小數點位置示意圖
如果小數點隱含固定在數值的某一位置上,即為定點小數。
如果小數點固定在符號位之后,即為純小數。假設機器字長為16位,符號位占一位,數值部分占15位,于是機器數1000000000000001的等效十進制數為-2-15,其符號位、數值部分、小數點的位置示意圖如圖1-20所示。

圖1-20 純小數的符號位、數值部分和小數點位置示意圖
2.浮點數
所謂浮點數,是指計算機中數的小數點位置不是固定的,或者說是“浮動”的。在計算機中,浮點數法一般用來表示實數,可以采用“階碼表示法”來表示浮點數,它由整數部分和小數部分組成,一個實數可以表示成一個純小數和一個乘冪之積。
采用浮點數最大的特點是,比定點數表示的范圍大。
例如,對于十進制數56.725=102×0.56725;對于二進制數110.11=22×1.1011。
對于任何一個二進制數N,都可以表示為
N=(2±E)×(±S)
浮點數在計算機中的編碼基本格式如圖1-21所示。

圖1-21 浮點數在計算機中的編碼基本格式
其中,E稱為階碼,階碼為0表示E為正,為1表示E為負。由此可見,小數點的實際位置隨著階碼E的大小和符號而浮動決定;±S為全部有效數據,稱為尾數部分。
例如,1001.011=20100×(0.1001011)。此處,0100部分稱為階碼且為正,(0.1001011)部分稱為尾數。
浮點數的格式多種多樣。例如,某計算機用4個字節表示浮點數,階碼部分為8位補碼定點整數,尾數部分為24位補碼定點小數,如圖1-22所示。

圖1-22 4個字節表示的浮點數
【例1-5】 描述用4個字節存放十進制浮點數“136.5”的浮點格式。
【解】 由于(136.5)10=(10001000.1)2,將二進制數“10001000.1”進行規格化,即
10001000.1=0.100010001×28
階碼28表示階符為“+”,階碼為“8”的二進制數為“0001000”;尾數中的數符為“+”。小數值為“100010001”。
十進制小數“136.5”在計算機中的表示如圖1-23所示。

圖1-23 規格化后的浮點數
在實際應用時,由于階碼指數可使用不同的編碼(原碼、補碼等),尾數的格式和小數點的位置也可以有不同的規定,所以浮點數的表示方法不唯一,不同的計算機可以有不同的規定。
1.4.4 計算機中常用的編碼
計算機除了用于數值計算外,還要進行大量的文字信息處理,也就是要對表達各種文字信息的符號進行加工。例如計算機和外設如鍵盤、(字符)顯示器、打印機之間的通信都采用字符方式輸入/輸出。目前計算機中最常用的兩種編碼是美國信息交換標準代碼(ASCII碼)和二-十進制編碼(BCD碼)。
1.美國信息交換標準代碼(ASCII碼)
ASCII(American Standard Code for Information-Interchange)碼是美國信息交換標準代碼的簡稱,主要給西文字符進行編碼。它采用7位二進制數表示一個字符,包括32 個標點符號,10個阿拉伯數字,52個英文大小寫字母,34個控制符號,共128個。編碼與字符之間的對應關系如附錄A所示。
在計算機系統中,存儲單元的長度通常為8位二進制數(即一個字節),為了存取方便,規定一個存儲單元存放一個ASCⅡ碼,其中低7位表示字母本身的編碼,第8位(即bit7)用做奇偶校驗位或規定為零(通常如此)。因此,也可以認為ASCII碼的長度為8位。
奇偶校驗的主要目的是用于在數據傳輸過程中,檢測接收方的數據是否正確。收發雙方預約為何種校驗,接收方收到數據后檢驗1的個數,判斷是否與預約的校驗相符,倘若不符,則說明傳輸出錯,可請求重新發送。奇校驗時,bit7的取值應使得8位ASCII碼中1的個數為奇數;偶校驗時,bit7的取值應使得ASCII碼中1的個數是偶數。例如:
“8”的奇校驗ASCII碼為00111000B,偶校驗ASCII碼為10111000B。
“B”的奇校驗ASCII碼為11000010B,偶校驗ASCII碼為01000010B。
2.BCD碼(二進制編碼的十進制數)
十進制畢竟是人們最習慣的計數方式,在向計算機輸入數據時,常用十進制數輸入,但計算機只識別二進制數,因此每1位十進制必須用二進制數表示。1位十進制數包含0~9十個數碼,必須用4位二進制數表示,這樣就需要確定0~9與4位二進制數0000B~1111B之間的對應關系,其中較常用的8421BCD碼規定了十進制數0~9與4位二進制數編碼之間的對應關系,見表1-6。
表1-6 十進制數與4位二進制數編碼之間的對應關系

注:在BCD碼中,不使用1010B(0AH)~1111B(0FH)。
例如,4567.89的BCD碼為0100010101100111.10001001(每1位十進位數用相應的4位二進制數表示即可)。BCD碼的一個優點就是10個BCD碼組合格式容易記憶。一旦熟悉了4位二進制數的表示,對BCD碼就可以像十進制數一樣迅速自如地讀出。同樣,也可以很快地得出以BCD碼表示的十進制數。例如,將1 個BCD數轉換成相應的十進制數:
(011101101001.100100110101)BCD=769.935
BCD碼采用4位編碼,4位一組表示1位十進制數,分別表示十進制數的個位、十位、百位等,低4位對高4位的進位為“逢十進一”。它不是二進制數,而是按4位二進制數的展開值和按4位一組解釋為十進制數。BCD碼和二進制數之間的轉換不能直接實現,二進制數轉換為BCD碼時,必須先將其轉換為十進制數。例如,要將二進制數1101.1B轉換為BCD碼,首先需要將二進制數按權展開,轉換為十進制數,再轉換為BCD碼:
1101.1B=1×23+1×22+0×21+1×20+1×2-1=13.5
13.5=(00010011.0101)BCD
同樣,要將BCD碼轉換為二進制數,首先要把BCD碼轉換為十進制數,然后再轉換為二進制數。
BCD編碼可以簡化人機關系,但它比純二進制編碼的效率低。對同一個給定的十進制數,用BCD編碼表示的位數比用純二進制表示的位數要多。而每位數都需要某些數字電路與之對應,這就使得與BCD碼連接的附加電路成本提高,設備的復雜性增加,功耗較大。用BCD碼進行運算所花的時間比用純二進制碼進行運算所花的時間要多,而且復雜。
計算機中存儲BCD碼的形式有兩種:壓縮BCD碼和非壓縮BCD碼。
(1)壓縮BCD碼
壓縮BCD碼用4位二進制數表示1位十進制數,一個字節可以表示2位十進制數。例如10010111B表示十進制數97。
(2)非壓縮BCD碼
非壓縮BCD碼用8位二進制數表示1位十進制數,高4位總為0000,低4位的0000~1001表示0~9。例如00001001B表示十進制數9。
盡管BCD碼比較直觀,但BCD碼與二進制數之間的轉換并不方便,需要轉換成十進數后,才能轉換為二進制數,反之亦然。
前面介紹了在使用計算機時二進制數、十進制數、十六進制數、ASCII碼、BCD碼以及帶符號數的表示等問題,這里要注意微型計算機能處理的數據只有二進制數,計算機并不認識什么正數、負數、BCD碼、ASCII碼等,計算機中數的表現形式只有二進制數,其他的數制和性質需要人們來進行分析與說明。如在某存儲器中存放一個二進制數11111111B(0FFH),這個數多大?這要看人們如何看了,如果是一個無符號數,就是255;如果是一個有符號數,就是-1;如果是個BCD碼,就是一個無效的數;如果是個ASCII碼,就代表“DEL”鍵的ASCII碼值。