計(jì)算機(jī)程序基礎(chǔ)教程(01):計(jì)算機(jī)運(yùn)行原理
【計(jì)算機(jī)的基礎(chǔ)原理】
計(jì)算機(jī)的運(yùn)行是以邏輯電路為基礎(chǔ)的,首先我們復(fù)習(xí)一下初中物理電路知識(shí),了解邏輯電路的基礎(chǔ)原理。
在電路中放置一個(gè)可以移動(dòng)的銜鐵,改變銜鐵的位置可以控制電路連接或斷開(kāi)。銜鐵平時(shí)依靠彈性呈斷開(kāi)電路狀態(tài),在銜鐵附近放置一個(gè)電磁鐵,電磁鐵通電產(chǎn)生磁性,吸引銜鐵移動(dòng),將電路閉合,電路即可通電。這種通過(guò)電磁鐵控制電路開(kāi)關(guān)的器件稱為電磁繼電器。
當(dāng)然芯片內(nèi)部不可能將電磁鐵放進(jìn)去,芯片內(nèi)的器件是用納米級(jí)工藝刻出來(lái)的,至于怎么刻,那是半導(dǎo)體物理學(xué)的研究范疇,我們無(wú)需關(guān)心。
使用繼電器可以制作出三種基本的邏輯運(yùn)算單元:與、或、非。
與運(yùn)算,電路中放置兩個(gè)繼電器,兩個(gè)繼電器全部通電時(shí),電路通電,可以使用串聯(lián)電路實(shí)現(xiàn)。
或運(yùn)算,電路中放置兩個(gè)繼電器,兩個(gè)繼電器有一個(gè)通電時(shí),電路即可通電,可以使用并聯(lián)電路實(shí)現(xiàn)。
非運(yùn)算,電路中放置一個(gè)繼電器,將電路通電狀態(tài)取反,通電變?yōu)椴煌姡煌娮優(yōu)橥姟?/p>
計(jì)算機(jī)使用帶電與不帶電兩種狀態(tài)表示二進(jìn)制數(shù)中的0和1,對(duì)于不產(chǎn)生進(jìn)位的二進(jìn)制加法可以使用或運(yùn)算實(shí)現(xiàn),分別比較兩個(gè)數(shù)據(jù)中相同位置的數(shù)字是否至少有一個(gè)為1,是的話計(jì)算結(jié)果此位為1,否則此位為0。

但是加法運(yùn)算是不可能避免產(chǎn)生進(jìn)位的,加法器可以首先使用與運(yùn)算判斷兩個(gè)數(shù)字是否都為1,是的話則產(chǎn)生一個(gè)進(jìn)位,否則再進(jìn)行或運(yùn)算,完整的加法器計(jì)算兩個(gè)數(shù)據(jù)相加時(shí),每個(gè)二進(jìn)制位都會(huì)計(jì)算3個(gè)數(shù)字相加,分別是兩個(gè)加數(shù)和一個(gè)進(jìn)位值,實(shí)現(xiàn)方式很簡(jiǎn)單。
而設(shè)計(jì)一個(gè)減法器會(huì)復(fù)雜的多,首先判斷一種簡(jiǎn)單的情況,兩個(gè)減數(shù)相同位置的數(shù)字是否相等,若都為0或都為1,則計(jì)算結(jié)果此位為0;之后再判斷相同位置中只有一個(gè)1的情況,若被減數(shù)為0、減數(shù)為1,則被減數(shù)需要向高位借位,如果緊鄰的高位為0,還需要向更高的位借位,一次減法運(yùn)算可能會(huì)產(chǎn)生多次借位;如果被減數(shù)小于減數(shù),計(jì)算結(jié)果為負(fù),這種情況會(huì)更復(fù)雜;這些問(wèn)題導(dǎo)致減法器的設(shè)計(jì)要比加法器復(fù)雜很多,運(yùn)算速度也要慢得多。
為了增加減法運(yùn)算的速度,計(jì)算機(jī)使用加法代替減法。
使用十進(jìn)制數(shù)來(lái)說(shuō)明轉(zhuǎn)換原理:
9 - 3 = 6
可以轉(zhuǎn)換為
9 + 7 = 16,去除十位 = 6
轉(zhuǎn)換原理很簡(jiǎn)單,因?yàn)?-3 與 +7 的結(jié)果正好相差10,所以 -3 轉(zhuǎn)換為 +7 之后只需要再減10即可,而減10可以無(wú)需計(jì)算,只需要不保留進(jìn)位產(chǎn)生的高位即可。
3和7相加的結(jié)果可以產(chǎn)生一個(gè)進(jìn)位,并且低位全為0,這兩個(gè)數(shù)滿足相加結(jié)果去除高位后等于減10的條件,那3和7就可以稱為彼此的補(bǔ)數(shù)。
對(duì)于 9 - 3 運(yùn)算,只需要計(jì)算出3的補(bǔ)數(shù)即可將減法轉(zhuǎn)換為加法,3的補(bǔ)數(shù)計(jì)算方式為 10 - 3 = 7,我們需要將減法轉(zhuǎn)換為加法,而計(jì)算補(bǔ)數(shù)時(shí)卻又產(chǎn)生了另一個(gè)減法,這個(gè)問(wèn)題在十進(jìn)制中很難解決,而在二進(jìn)制數(shù)中卻非常的簡(jiǎn)單。
補(bǔ)數(shù)的目的就是讓兩個(gè)數(shù)相加后產(chǎn)生一個(gè)進(jìn)位,并且低位全是0,在二進(jìn)制加法中,如果兩個(gè)數(shù)的每個(gè)位都相反,那計(jì)算結(jié)果的每個(gè)位都為1,比如 1010 + 0101 = 1111,這個(gè)結(jié)果再 +1 就會(huì)產(chǎn)生進(jìn)位,并且低位全是0。
所以我們計(jì)算 1010 的補(bǔ)數(shù)時(shí),只需要將其每個(gè)位取反值,得到 0101,之后再 +1 即可,取反與 +1 可以合并為一個(gè)步驟,這樣就得到了 1010 的補(bǔ)數(shù)為 0110。
?● 正負(fù)數(shù)的表示方式
計(jì)算機(jī)將一個(gè)數(shù)據(jù)按照是否有正負(fù)號(hào)分為兩種類型:有符號(hào)數(shù)、無(wú)符號(hào)數(shù)。
對(duì)于有符號(hào)數(shù),其最高位表示正負(fù)號(hào),0表示正,1表示負(fù),若一個(gè)數(shù)據(jù)是負(fù)數(shù),則使用它的補(bǔ)碼(補(bǔ)數(shù))存儲(chǔ),因?yàn)樨?fù)數(shù)本質(zhì)上是一個(gè)減數(shù),直接存儲(chǔ)其補(bǔ)碼方便運(yùn)算。
對(duì)于無(wú)符號(hào)數(shù),只能表示正數(shù),其所有的二進(jìn)制位都用來(lái)表示數(shù)值。
示例,使用一個(gè)8位二進(jìn)制數(shù)表示-5:
最高的符號(hào)位設(shè)置為1,表示負(fù)數(shù),5轉(zhuǎn)換為二進(jìn)制等于101,負(fù)數(shù)使用補(bǔ)碼存儲(chǔ),根據(jù)取反加一的規(guī)則,其補(bǔ)碼為111 1011,符號(hào)位與數(shù)值位整合后編碼為:1 111 1011
?● 計(jì)算結(jié)果為負(fù)數(shù)的情況
用10進(jìn)制數(shù)來(lái)說(shuō)明:
5 - 6 = -1
將減法轉(zhuǎn)換為加法,6的補(bǔ)數(shù)為4,5 + 4 = 9,顯然9并不是 5 - 6 的結(jié)果。
當(dāng)減法結(jié)果為負(fù)數(shù)時(shí),被減數(shù)小于減數(shù),此時(shí)被減數(shù)加減數(shù)的補(bǔ)數(shù)必定不會(huì)產(chǎn)生進(jìn)位,計(jì)算結(jié)果也就沒(méi)有去除高位這一步驟,導(dǎo)致結(jié)果比正確值大10。
若想得到正確結(jié)果,我們需要自行減去10,9 - 10 = -1, 從而得到 5 - 6 的正確結(jié)果。
但是不減10的話,此數(shù)據(jù)正是減法結(jié)果的補(bǔ)數(shù),在計(jì)算機(jī)中負(fù)數(shù)是使用補(bǔ)碼存儲(chǔ)的,所以此時(shí)直接存儲(chǔ)補(bǔ)數(shù)即可。
總結(jié):計(jì)算機(jī)使用加補(bǔ)碼的方式進(jìn)行減法運(yùn)算時(shí),若不會(huì)產(chǎn)生導(dǎo)致溢出的進(jìn)位,則CPU會(huì)認(rèn)為計(jì)算結(jié)果是個(gè)負(fù)數(shù),將結(jié)果的符號(hào)位設(shè)置為1,之后直接存儲(chǔ)計(jì)算出來(lái)的補(bǔ)碼。
?● 正0與負(fù)0編碼重復(fù)的問(wèn)題
對(duì)于有符號(hào)數(shù)來(lái)說(shuō),每個(gè)數(shù)據(jù)都有正負(fù)之分,但是將0分為+0和-0顯然不合理,所以計(jì)算機(jī)使用-0表示有符號(hào)數(shù)能夠表示的最大負(fù)值再減1。
比如一個(gè)8位的有符號(hào)數(shù),去除最高位的符號(hào)位,剩余7位用來(lái)表示數(shù)值,二進(jìn)制111 1111等于十進(jìn)制127,所以它的表示范圍是 +127 到 -128,其中-128使用-0表示。
那使用-0表示-128是否會(huì)引發(fā)混亂呢,其實(shí)并不會(huì),在8位有符號(hào)數(shù)中,-128為最小的負(fù)數(shù),不能再減,減1等于-129,超出表示范圍,發(fā)生溢出,這種運(yùn)算本身就是錯(cuò)誤的,肯定會(huì)得到錯(cuò)誤結(jié)果,錯(cuò)上加錯(cuò)也無(wú)所謂,但是可以再加,加1等于-127,-127可以使用正常編碼方式表示。
【計(jì)算機(jī)表示小數(shù)的方式】
3.1415926 可以使用如下科學(xué)計(jì)數(shù)法表示:
31415926 × 10^7
0.31415926 × 10^-1
計(jì)算機(jī)中小數(shù)的表示方式類似科學(xué)計(jì)數(shù)法,只不過(guò)乘方底數(shù)由10改為2,原因是二進(jìn)制數(shù)需要乘2才會(huì)向高位移動(dòng)一位,使用科學(xué)計(jì)數(shù)法表示小數(shù)的方式也稱為浮點(diǎn)表示法。
使用浮點(diǎn)表示法的原因是為了利用其可以移動(dòng)小數(shù)點(diǎn)的特點(diǎn),將存儲(chǔ)器中的每一個(gè)位都利用起來(lái),避免造成浪費(fèi),同時(shí)也可以使用長(zhǎng)度有限的存儲(chǔ)單元表示長(zhǎng)度更大的小數(shù)。
若不使用浮點(diǎn)表示法,則我們只能約定小數(shù)點(diǎn)在數(shù)據(jù)中固定的位置,比如一個(gè)長(zhǎng)度32位的二進(jìn)制數(shù)據(jù),我們可以約定前16位表示整數(shù),后16位表示小數(shù),若小數(shù)為0.xxx,則整數(shù)位會(huì)浪費(fèi)掉,若小數(shù)為xxx.0,則小數(shù)位會(huì)浪費(fèi)掉。
?● 浮點(diǎn)數(shù)的組成部分
浮點(diǎn)數(shù)由三部分組成:符號(hào)位、階碼、尾數(shù)。
符號(hào)位,表示小數(shù)的正負(fù)號(hào)。
階碼,表示乘方的指數(shù)。
尾數(shù),科學(xué)計(jì)數(shù)法的尾數(shù),它的數(shù)據(jù)全部用來(lái)表示小數(shù)位,可以通過(guò)改變階碼的值來(lái)移動(dòng)小數(shù)點(diǎn)的位置,從而表示整數(shù)位不為0的小數(shù)。
乘方的底數(shù)因?yàn)楣潭?,所以無(wú)需使用任何存儲(chǔ)元件存儲(chǔ),這是計(jì)算機(jī)的一種約定,從而節(jié)省存儲(chǔ)空間。
?● 浮點(diǎn)數(shù)各部分的長(zhǎng)度以及排列方式
浮點(diǎn)數(shù)中符號(hào)位占用最高位,之后是階碼,最后是尾數(shù),IEEE754標(biāo)準(zhǔn)規(guī)定了三種浮點(diǎn)數(shù)類型,分別如下:
單精度浮點(diǎn)數(shù),長(zhǎng)度4字節(jié),符號(hào)位占1位,階碼長(zhǎng)度8位,尾數(shù)長(zhǎng)度23位。
雙精度浮點(diǎn)數(shù),長(zhǎng)度8字節(jié),符號(hào)位占1位,階碼長(zhǎng)度11位,尾數(shù)長(zhǎng)度52位。
擴(kuò)展雙精度浮點(diǎn)數(shù),長(zhǎng)度10字節(jié),符號(hào)位占1位,階碼長(zhǎng)度15位,尾數(shù)長(zhǎng)度64位。
?● 階碼表示指數(shù)的方式
階碼自身沒(méi)有符號(hào)位,這樣可以讓長(zhǎng)度有限的階碼表示更大范圍的指數(shù),但指數(shù)是需要表示負(fù)數(shù)的,那沒(méi)有符號(hào)位的階碼如何表示負(fù)數(shù)呢。
實(shí)際上計(jì)算機(jī)是讓指數(shù)加一個(gè)數(shù)值表示階碼,將有符號(hào)數(shù)的所有數(shù)值范圍映射到無(wú)符號(hào)數(shù)中,從而避開(kāi)負(fù)數(shù)。單精度浮點(diǎn)數(shù)加127,雙精度浮點(diǎn)數(shù)加1023,擴(kuò)展雙精度浮點(diǎn)數(shù)加16383,這里將增加的數(shù)稱為校正值。
以單精度浮點(diǎn)數(shù)為例:
若指數(shù)用于表示 -127 - 0,則加127后等于 0 - 127,階碼使用 0 - 127 表示指數(shù)的 -127 - 0。
若指數(shù)用于表示 1 - 128,則加127后等于 128 - 255,階碼使用 128 - 255 表示指數(shù)的 1 - 128。
?● 浮點(diǎn)數(shù)的規(guī)格化
如果浮點(diǎn)數(shù)用來(lái)表示一個(gè)整數(shù)位為0的十進(jìn)制小數(shù),則轉(zhuǎn)換為二進(jìn)制后,小數(shù)位的高位可能會(huì)有很多0,比如 0.375 轉(zhuǎn)換為二進(jìn)制為 0.011。
為了節(jié)省存儲(chǔ)空間,浮點(diǎn)數(shù)的尾數(shù)部分不存儲(chǔ)這些高位的0,空出的存儲(chǔ)元件可以存儲(chǔ)更多的低位值,從而增加浮點(diǎn)數(shù)的精度,由此導(dǎo)致尾數(shù)與原值不同的問(wèn)題,需要通過(guò)修改指數(shù)的方式來(lái)將尾數(shù)還原,比如上述的0.011可以這樣記錄:0.11 × 10^-1。
既然尾數(shù)的最高位必須是1,那這個(gè)位其實(shí)也可以省略,從而又節(jié)省一位存儲(chǔ)元件,大家都遵循此約定,使用浮點(diǎn)數(shù)時(shí)再加上這個(gè)省略的1即可。
因?yàn)樽罡呶坏?被省略,尾數(shù)的次高位變成了最高位,導(dǎo)致尾數(shù)又向高位移動(dòng)了一位,所以此時(shí)需要將指數(shù)再減1,還原尾數(shù)的原值。
比如0.011,使用浮點(diǎn)表示法應(yīng)該存儲(chǔ)為 0.1 ×?10^-2,其中小數(shù)位包含一位隱藏的高位1,你也可以認(rèn)為是 1.1 ×?10^-2,只不過(guò)整數(shù)位的1不會(huì)被存儲(chǔ)。
實(shí)際上只有單精度、雙精度浮點(diǎn)數(shù)會(huì)省略最高位的1,而擴(kuò)展雙精度浮點(diǎn)數(shù)最高位1不能省略,這是IEEE754標(biāo)準(zhǔn)的規(guī)定。
?● 浮點(diǎn)數(shù)編碼示例
示例1:?jiǎn)尉雀↑c(diǎn)數(shù) 0.625
0.625轉(zhuǎn)換為二進(jìn)制為0.101,使用浮點(diǎn)表示法時(shí)各部分的值如下:
符號(hào)位,這里是正數(shù),符號(hào)位設(shè)置為0。
階碼,因?yàn)槲矓?shù)最高位的1被隱藏,次高位變成了最高位,尾數(shù)向高位移動(dòng)了一位,所以需要將指數(shù)設(shè)置為-1,還原尾數(shù)原值,指數(shù)加校正值得出階碼,-1 + 127 = 126,轉(zhuǎn)換為二進(jìn)制等于 0111 1110。
尾數(shù)原值為101,最高位的1被省略,所以尾數(shù)存儲(chǔ)為01。
最終編碼為:0 01111110 01000000000000000000000 ,其中尾數(shù)長(zhǎng)23位。
示例2:?jiǎn)尉雀↑c(diǎn)數(shù) -0.375
0.375轉(zhuǎn)換為二進(jìn)制為0.011,浮點(diǎn)數(shù)各部分編碼如下:
符號(hào)位為1,表示負(fù)數(shù)。
階碼,尾數(shù)首先需要向高位移動(dòng)一位,去除最高位的0,之后將最高位的1隱藏,尾數(shù)總共向高位移動(dòng)了兩位,所以指數(shù)應(yīng)該設(shè)置為-2,-2 + 127 = 125,轉(zhuǎn)換為二進(jìn)制等于 0111 1101。
尾數(shù)原值為011,高位的0和1不存儲(chǔ),實(shí)際存儲(chǔ)為1。
最終編碼為:1 01111101 10000000000000000000000
【計(jì)算機(jī)硬件的基本結(jié)構(gòu)】
計(jì)算機(jī)主要由如下4個(gè)部分組成:
中央處理器,就是大家經(jīng)常說(shuō)的CPU,起控制和運(yùn)算功能。
存儲(chǔ)器,用于存儲(chǔ)二進(jìn)制數(shù)據(jù)。
輸入設(shè)備,用于向CPU輸入數(shù)據(jù),比如鍵盤、鼠標(biāo)。
輸出設(shè)備,接收CPU發(fā)出的數(shù)據(jù),比如顯示器、音響。
?● 存儲(chǔ)器
計(jì)算機(jī)中將一個(gè)二進(jìn)制數(shù)字稱為一個(gè)比特位,英文名bit,簡(jiǎn)寫為小寫b。
將8個(gè)比特位組成一組使用,稱為一個(gè)字節(jié),英文名Byte,簡(jiǎn)寫為大寫B(tài)。
1024B? = 1KB
1024KB = 1MB
1024MB = 1GB
1024GB = 1TB
1024TB = 1PB
1024PB = 1EB
1024EB = 1ZB
1024ZB = 1YB
存儲(chǔ)器中用于存儲(chǔ)一個(gè)字節(jié)的部件稱為存儲(chǔ)單元,每個(gè)存儲(chǔ)單元內(nèi)部有8個(gè)存儲(chǔ)元件,用來(lái)存儲(chǔ)8個(gè)比特位。
存儲(chǔ)器按照功能的不同可以分為兩類:主存、輔存,對(duì)應(yīng)內(nèi)存和硬盤。
主存讀寫速度很快,但是斷電后數(shù)據(jù)無(wú)法保存,用于在計(jì)算機(jī)運(yùn)行時(shí)臨時(shí)存儲(chǔ)處理器需要使用的數(shù)據(jù)。
輔存讀寫速度慢一些,但是斷電后數(shù)據(jù)依然可以保存,用于在計(jì)算機(jī)斷電停止運(yùn)行后保存數(shù)據(jù),為了降低成本,一般是將多個(gè)存儲(chǔ)單元組成一組使用,一組稱為一個(gè)頁(yè),頁(yè)的容量可以是512B、1KB、2KB等等容量,每個(gè)頁(yè)使用一條地址線與外界相連,讀寫數(shù)據(jù)時(shí)至少操作一個(gè)頁(yè)。
?● 中央處理器
中央處理器是通過(guò)納米級(jí)工藝制作的大規(guī)模集成電路,內(nèi)部主要分為4個(gè)部分:控制器、運(yùn)算器、緩存、寄存器。
控制器用來(lái)執(zhí)行CPU對(duì)外提供的一些功能,控制器的工作需要由指令決定,指令是一些CPU能夠識(shí)別的固定格式的數(shù)據(jù),一條指令表示一種具體的功能,控制器通過(guò)不斷的在存儲(chǔ)器中讀取指令數(shù)據(jù)從而不間斷的工作。
運(yùn)算器負(fù)責(zé)進(jìn)行數(shù)學(xué)運(yùn)算、邏輯運(yùn)算、位移運(yùn)算。
緩存是一種讀寫數(shù)據(jù)速度比內(nèi)存更快的存儲(chǔ)器,內(nèi)存讀寫速度雖然很快,但還跟不上CPU處理數(shù)據(jù)的速度,所以CPU在讀取內(nèi)存數(shù)據(jù)時(shí),會(huì)將其周圍的數(shù)據(jù)一并讀取出來(lái),然后存儲(chǔ)到緩存中,之后直接從緩存中讀取數(shù)據(jù)。
寄存器是一種比緩存讀寫速度更快的存儲(chǔ)器,一般用于存儲(chǔ)程序執(zhí)行時(shí)頻繁使用的數(shù)據(jù),但寄存器數(shù)量有限,程序執(zhí)行期間并不會(huì)將所有的數(shù)據(jù)都存放在寄存器中。
?● 地址空間
CPU使用一個(gè)數(shù)據(jù)指定要讀寫的存儲(chǔ)單元,稱為地址,地址能夠表示的數(shù)值范圍稱為地址空間。
比如32位的CPU可以使用一個(gè)4字節(jié)的數(shù)據(jù)當(dāng)做地址,總共可以尋址42,9496,7295個(gè)存儲(chǔ)單元。
地址空間分為兩種:內(nèi)存地址空間、IO地址空間,分別分配給內(nèi)存和輸入輸出設(shè)備,兩個(gè)地址空間使用不同的指令進(jìn)行讀寫。
IO地址空間的不同范圍會(huì)分配給不同的設(shè)備總線,CPU通過(guò)讀寫不同范圍的IO地址空間控制設(shè)備總線中的不同硬件設(shè)備,硬盤是連接在IO地址空間的,CPU將其當(dāng)做IO設(shè)備管理。