人丑就得多讀書,最近不得不承認呕童,我也得多讀書漆际,讀書就得多總結(jié),不然會忘夺饲。
今天是Christmas Eve(寫完估計就圣誕了)奸汇,同時也是我的生日(寫完估計就不是了),其實我是過農(nóng)歷的往声,所以今天才是真正官方認證的生日擂找,之前公歷那個就算欺騙大家感情了。
值此雙喜之日浩销,我終于把《Linux C一站式編程》看完了贯涎,可是有很多不明白的地方,想寫點讀書筆記慢洋,梳理一下塘雳。今天就和大家一起簡單的梳理一下,關于計算機體系結(jié)構(gòu)基礎的一些概念普筹,我們整天談我們了解計算機败明,但是我們真正了解多少呢。我們一起梳理一下吧太防,以下以x86架構(gòu)為例妻顶。
聲明:內(nèi)容在發(fā)出之前,盡量做到仔細校訂蜒车,若有覆蓋不全讳嘱,或者明顯錯誤的地方,請幫我指出來酿愧,幫助我進步沥潭。
CPU
那就先從CPU開始講吧,CPU最核心的部件嬉挡,包括以下幾個:
- 寄存器
寄存器就是CPU內(nèi)部的高速存儲器叛氨,像內(nèi)存一樣可以存取數(shù)據(jù),但是速度比內(nèi)存快很多棘伴,為什么快呢寞埠,可以看看阮一峰的[這篇](http://www.ruanyifeng.com/blog/2013/10/register.html)科普文章。
CPU內(nèi)部的寄存器通常分為兩種焊夸,一種是通用寄存器仁连,比如eax,可以用于運算和讀寫內(nèi)存的過程中;有的是特殊寄存器饭冬,比如eip使鹅,用于程序計數(shù)器。
- 程序計數(shù)器(PC)
在x86體系結(jié)構(gòu)中昌抠,通常是eip患朱,這里面保存這CPU的取指地址,CPU從PC中讀取指令地址炊苫,然后去內(nèi)存中取指令執(zhí)行裁厅,然后PC中保存的地址自動加上該條指令的長度,指向內(nèi)存中的下一條指令侨艾,CPU一直在重復這項工作执虹。
- 指令譯碼器(Instruction Decoder)
CPU根據(jù)PC中的地址,從內(nèi)存中讀取到某條指令以后唠梨,指令的內(nèi)容其實就是0和1的各種組合袋励,有些位的組合表示一個寄存器,有些位的組合表示一種操作当叭,ID負責解釋這條指令的含義茬故,然后調(diào)用相關的執(zhí)行單元去執(zhí)行。
- 算數(shù)邏輯單元(ALU)
上面講到的執(zhí)行單元的一種蚁鳖,如果譯碼器將指令解釋為運算指令磺芭,就調(diào)動ALU去運算笨篷,指令中會指定結(jié)果保存在什么地方亿汞,運算結(jié)果可能保存在寄存器或者是內(nèi)存單元中,這都不是事。
- 三總線
CPU和內(nèi)存之間通過三條總線相連琅攘,分別是地址總線,數(shù)據(jù)總線和控制總線松邪,每條總線上的狀態(tài)根據(jù)電勢高低坞琴,分為0和1。如果在指令執(zhí)行過程中逗抑,指令需要讀取內(nèi)存某個地址數(shù)據(jù)到寄存器中剧辐,整個過程可以想象成一下這個樣子
* CPU將寄存器的每個位,對接到數(shù)據(jù)總線的每位上邮府,等待接收數(shù)據(jù)
* 然后CPU將地址通過地址總線發(fā)送給內(nèi)存單元
* 然后用控制總線發(fā)送讀數(shù)據(jù)請求
* 內(nèi)存收到讀請求和地址以后荧关,就將對應地址的存儲單元對接到數(shù)據(jù)總線的另一端,這樣每一位的狀態(tài)就到達了寄存器中相應的位褂傀,完成了數(shù)據(jù)傳輸
- 32/64位
一般來說忍啤,地址線、數(shù)據(jù)線和CPU寄存器的位數(shù)是一致的仙辟,因為寄存器讀數(shù)據(jù)需要對接數(shù)據(jù)線同波,寄存器有時又需要保存地址鳄梅,比如寄存器間接尋址,所以三者是一致的未檩,一般32位體系結(jié)構(gòu)就是32位戴尸,64位也是一樣,處理器的位數(shù)又叫做字長冤狡。32位計算機共有32根地址線孙蒙,可尋址空間位4G,64位更大筒溃。
以上算是把CPU內(nèi)部的一些主要部件講完了马篮,但是有一些需要注意的地方,上面講的總線都是內(nèi)總線怜奖,直接和執(zhí)行單元相連接浑测,內(nèi)總線經(jīng)過MMU和總線接口的轉(zhuǎn)換引出到芯片引腳才是外總線,外總線的位數(shù)有可能和內(nèi)總線不一樣歪玲,所以32位處理器的外地址總線可尋址范圍是可以大于4G的迁央。至于內(nèi)外地址線的轉(zhuǎn)換以及MMU的功能,等我請教完老師傅滥崩,繼續(xù)看點書再和大家掰掰岖圈,先按下不表了。
外設
講完了CPU的內(nèi)件钙皮,接下來就走出CPU蜂科,看看外面的世界,講講外設吧短条。
計算機強大之處导匣,以及被應用到各個場景里面的一個很重要的原因就是可以接很多奇奇怪怪的外部設備,老一點的比如鍵盤茸时、鼠標贡定,流行一點的各種體感設備,數(shù)位板等可都。那各式各樣的外設如何與計算機交互缓待,如何于CPU連接的呢?我們就來探探渠牲。
本來想先放一張圖鎮(zhèn)樓的旋炒,可是找不到好的圖床,就先干巴巴的說吧签杈。
- 設備寄存器
有些設備和內(nèi)存芯片一樣直接架在總線上瘫镇,但是不同的設備需要占用不同的地址空間,訪問這種設備就像訪問內(nèi)存一樣按照地址讀寫,往地址發(fā)數(shù)據(jù)汇四,數(shù)據(jù)不一定會被保存接奈,而讀取也不一定是保存在設備中的數(shù)據(jù),可能是設備當前的狀態(tài)通孽,設備中可供讀寫的單元稱為設備寄存器序宦,操作過程就是讀寫這些設備的寄存器,比如串口設備背苦。
- 內(nèi)存映射I/O
還有一些設備是繼承在處理器芯片中的互捌,從CPU核心引出的總線分為兩端,一端是經(jīng)總線接口到引腳了行剂,還有一段接在了芯片內(nèi)部的設備上秕噪,無論內(nèi)部總線設備還是外部總線設備,都有各自的地址范圍厚宰,即都可以像內(nèi)存一樣訪問腌巾,這種方式成為內(nèi)存映射IO,比如ARM體系結(jié)構(gòu)就是實用的這種方式铲觉。
- 端口I/O
對于另外一些體系結(jié)構(gòu)澈蝙,需要從CPU核心單獨引出額外的地址線來接到內(nèi)部設備上,訪問這些內(nèi)部設備寄存器的時候撵幽,需要使用特殊的指令in/out灯荧,這種方式稱為端口I/O,x86就是這種體系架構(gòu)
- 設備總線和設備控制器
對于CPU而言盐杂,操作設備的方式只有內(nèi)存映射和端口兩種方式逗载,但是外部設備的種類有很多,需求也很不一樣链烈,比如有的需要高性能讀寫厉斟,有的需要支持熱插拔等,為了滿足各種不同的需求测垛,出現(xiàn)了各種不同的設備總線捏膨,比如PCI秧均、AGP食侮、USB和SATA等。這些總線并不是直接與CPU連接的目胡,CPU通過內(nèi)存映射或者是端口方式訪問設備控制器锯七,設備控制器再去訪問掛在設備總線上的各種設備。
比如在x86系統(tǒng)上誉己,硬盤通常掛載在ATA眉尸、SATA或者SCSI總線上,保存在硬盤上的指令是不能被CPU直接取指的,操作系統(tǒng)執(zhí)行程序的時候噪猾,會將指令從硬盤拷貝到內(nèi)存霉祸,然后從內(nèi)存中取指,這個過程稱為『加載』袱蜡,程序加載到內(nèi)存丝蹭,成為操作系統(tǒng)可調(diào)度執(zhí)行的任務,成為進程坪蚁。
操作系統(tǒng)內(nèi)核也是一樣奔穿,計算機啟動的時候執(zhí)行一段固定的代碼,固定指的是地址固定敏晤,稱為啟動代碼(bootloader)贱田,這是一段很短小精悍的代碼,當年我的老師這么和我說的嘴脾。這段代碼首先把操作系統(tǒng)從磁盤加載到內(nèi)存中男摧,然后執(zhí)行操作系統(tǒng)中的代碼,把用戶需要的程序加載到內(nèi)存中译打,操作系統(tǒng)最核心的功能就是資源管理彩倚,包括進程調(diào)度,內(nèi)存管理等扶平,這部分功能代碼叫做內(nèi)核帆离。
- 中斷(Interrupt)
設備和內(nèi)存有一個很不一樣的地方,就是內(nèi)存一般來說只是數(shù)據(jù)保存结澄,相對本機而言不會產(chǎn)生新的數(shù)據(jù)哥谷,他不會主動的提供數(shù)據(jù)給CPU。但是設備卻不同麻献,通常都會自己產(chǎn)生數(shù)據(jù)们妥,需要主動通知CPU來取這些數(shù)據(jù),并做響應的處理勉吻,例如敲擊鍵盤监婶,活動的網(wǎng)卡等。這個通知就是通過中斷機制來實現(xiàn)的齿桃,每個設備都有一個中斷線惑惶,通過中斷控制器連接到CPU,當設備有數(shù)據(jù)產(chǎn)生短纵,就會觸發(fā)一個中斷带污,通過中斷總線和中斷控制器通知到CPU,CPU當前正在執(zhí)行的指令被打斷香到,程序計數(shù)器被設置成一個固定的地址鱼冀,CPU跳轉(zhuǎn)到這個地址报破,開始執(zhí)行中斷服務程序(ISR),完成以后跳轉(zhuǎn)會原先執(zhí)行指令的地址千绪。
- 中斷服務程序(ISR)
ISR通常是由內(nèi)核提供的一段代碼充易,實現(xiàn)加載到一個固定的地址,當出現(xiàn)中斷請求的時候荸型,CPU跳轉(zhuǎn)過來執(zhí)行蔽氨。這段中首先判斷是哪個設備引發(fā)了中斷,然后調(diào)用該設備注冊的中斷處理函數(shù)做進一步處理帆疟,突然想起大學的時候鹉究,我和小伙伴在ACM實驗室,搞了一晚的基踪宠,才讓鍵盤引發(fā)中斷的時候自赔,調(diào)用我們寫的中斷處理程序,在屏幕上打印對應的鍵碼柳琢。
- 驅(qū)動程序
由于每種設備的中斷處理方法都不一樣绍妨,每種設備都需要提供對應的驅(qū)動程序,應用廣泛的操作系統(tǒng)柬脸,就需要有大量的驅(qū)動程序他去,設備驅(qū)動程序通常就是對設備寄存器的讀寫操作,有些設備需要在ISR注冊中斷處理程序倒堕。
好了灾测,今天差不多就總結(jié)了這么多,搬了一些東西加上自己的理解垦巴,雖然不夠細致媳搪,但也差不多弄清楚了從CPU內(nèi),到CPU外的架構(gòu)和通信骤宣,后續(xù)會深入到內(nèi)存里面去秦爆,看看虛擬內(nèi)存,以及計算機程序從匯編角度的理解憔披、二進制文件的內(nèi)容以及加載到內(nèi)存中的模樣等限,不過得我從老師傅那里取經(jīng)回來。
最后芬膝,還是值此圣誕佳節(jié)和我的生日望门,祝大家圣誕快樂,Merry Christmas.
多說一句蔗候,知乎常年招收Antispam工程師怒允,地址是這里埂软,簡歷可以發(fā)到hdd at zhihu dot com里面锈遥。