前言
書名:《編碼:隱匿在計算機軟硬件背后的語言》
英文名:Code: The Hidden Language of Computer Hardware and Software
作者:美國人Charles Petzold
去年買的書惨篱,讀了一遍總感覺沒讀透,也可能是讀了內(nèi)容忘了愚争,所以又讀了一遍嚼蚀。
簡單內(nèi)容(1-12章節(jié))
前面的內(nèi)容有上過大學的電氣辕录、電子玫鸟、計算機的學生看起來都不會很吃力,我把它分為幾個部分:
1.闡述信息的組成移稳,信息的主成有現(xiàn)象(光蕴纳、電、聲音个粱、文字古毛、圖像),并且包含現(xiàn)象的獲取順序都许,比如你把一句話的順序稻薇、主謂賓搞混了就和原來不是一回事了,還有我們閱讀的文字如果約定的順序不一樣獲得的信息也會不同(典型的就是古人的書寫習慣是先右后左)胶征,這種順序包含空間順序也包含時間順序塞椎。
2.從電報機聊到編碼,這個就比較直觀了比如摩斯電碼SOS是:··· --- ···
三短三長三短一般比較好辨認用于國際通用求助,在markdown里面 ```代表代碼塊睛低。不管是否加密案狠,總是接收方和發(fā)送方要達成一定的協(xié)議,否則通訊就無法進行钱雷。
3.根據(jù)繼電器的特點不是0就是1的兩種狀態(tài)骂铁,我們選擇使用二進制作為計算機的內(nèi)部語言。之后就繼電器的基礎模型詳細描述了《數(shù)字電路》里面講的邏輯門罩抗,最基礎的就是緩沖器拉庵、反相器、非澄暮、與名段、或、異或門四種邏輯門電路泣懊,還有他們的衍生組合:與非門伸辟、或非門、與或非門馍刮,基于這個概念我們就可以用繼電器或者三極管自己造出這些門信夫。
數(shù)字計算器的組成(13-17章)
使用數(shù)字電路邏輯門我們可以制作出譯碼器、振蕩器(蜂鳴器、晶振時鐘)静稻、R-S觸發(fā)器警没、D型鎖存器、選擇器振湾、邊沿觸發(fā)器杀迹、分頻器、計數(shù)器等押搪。
而加法器也沒有什么特殊的同樣是用邏輯門造出來的树酪,首先我們考慮兩個一位二進制數(shù)相加。畫出輸入輸出表格我們知道需要一個異或門大州。
(A || B) && !(A && B)=A XOR B //異或門
加和輸出:A XOR B
進位輸出位為:A && B
這種叫做半加器续语,兩個半加器和一個或門可以得到一個帶進位輸入的全加器。
8個全加器(7個全加器和1個半加器也行)就可以組成一個8位+8位的8位加法器厦画。
可以多重套娃用加法器疊加起來做16位疮茄、32位的加法器都沒問題。但是這種方法太浪費了根暑,如果讓你計算一個很大的數(shù)可能要造N多個加法器力试。
所以就需要用鎖存器(用觸發(fā)器組合)了,顧名思義就是用來存上一次的結果以便于用來進行下次運算排嫌,中間加一個選擇器用來控制B端輸入是鎖存器還是外界輸入懂版。這樣就得到一個加法器了。
自動操作的數(shù)字計算器
為了一次性輸完一組數(shù)讓他們自己去求和就需要兩個東西一個就是存數(shù)的RAM(隨機訪問存儲器)躏率、另一個是時鐘信號(拓展一下:51單片機晶振頻率12Mhz,一次機器周期等于12個時鐘周期就是1微妙)躯畴。
在一個8位鎖存器的W寫操作端添加一個3-8譯碼器進行W端有且僅有一個為1,在鎖存器輸出端添加一個8-1選擇器進行輸出選擇薇芝,如此定向輸出定向輸入蓬抄,三位用來控制地址、一位數(shù)據(jù)輸入夯到、一位寫操作端就可以管理8X1的RAM一共1byte字節(jié)的數(shù)據(jù)嚷缭。
把這套輸入和一個輸入位再加到另一個8X1的RAM上就可以組成一個8X2RAM一次可以得到兩個RAM的輸出。這樣縱向拓展下去可以無限套娃得到8XN的RAM耍贾,但是未免太傻了阅爽。一般情況是把N取8再進行橫向擴展,增加地址位得到一個65536(2的16次方)位鎖存器荐开,此時地址位為16付翁,輸入輸出8位,可以儲存65536個8比特位(1字節(jié))的數(shù)據(jù)晃听,共64KB(千字節(jié))百侧。
這大概需要由500萬個繼電器進行組裝砰识,所以RAM是需要帶電工作的,一旦掉電數(shù)據(jù)就丟失了佣渴。
有了這兩個東西就可以開始嘗試組裝一臺自動操作的計算器了辫狼,稍加改進就是一臺可以稱之為計算機computer的東西了。
自動加法器
利用16位計數(shù)器我們可以順序對RAM進行尋址辛润,那么我們就可以在RAM上面順序進行讀寫操作膨处,把需要相加的數(shù)據(jù)逐條輸入。之后裝上振蕩器并清零16位計數(shù)器砂竖,機器就像上了發(fā)條一樣灵迫,自動在時鐘信號的指揮下,逐條讀取數(shù)值與鎖存器數(shù)值進行加法操作晦溪,并把結果保存進鎖存器,然后如此循環(huán)挣跋。當計算結束后你必須馬上記錄結果三圆,不然一旦進入下一個尋址周期,那么結果就不準確了避咆。
概念機
如何讓機器聽話呢舟肉?再加上一片RAM用來存儲代碼就可以,這些代碼會影響機器的運行狀態(tài)查库,比如說控制加法器讀另一片RAM的數(shù)路媚、向鎖存器RAM寫數(shù)、比如說讓機器停下來不再受晶振影響樊销,這些需要把8位代碼的輸出用邏輯門和需要控制的器件連接整慎,達到控制他們的目的,進而控制機器運行围苫。而每一個代碼就對應一個英文操作碼方便人們閱讀裤园,之后精簡擴充后就是匯編語言。
通過對這個模型的優(yōu)化改進增加操作代碼集和控制元件的添加后剂府,還是發(fā)現(xiàn)這個機器比較笨重拧揽,因為它不能對之前保存的數(shù)進行訪問,原因在于數(shù)據(jù)塊RAM地址位的控制權不在代碼RAM手上腺占,因此把一個代碼擴充到3字節(jié)淤袜,分別保存1字節(jié)操作碼2字節(jié)地址。
經(jīng)過整合可以把兩塊RAM縮減到一塊衰伯,代碼RAM不但可以被讀也可以被寫铡羡。但是也造成一個指令周期變長為4個時鐘周期,縮小了機器性能意鲸。之后就是指令集和機器控制元件的一些小調整蓖墅。
機器的硬件和軟件組成都完成了库倘,就此創(chuàng)造了非凡機器的開端,萬惡之源论矾,由處理器教翩、儲存器、輸入輸出設備共同構造的數(shù)字計算機的時代贪壳。
其中處理器CPU包括:累加器和算術邏輯單元ALU饱亿,以及尋址用的程序計數(shù)器。
現(xiàn)在我們可以討論一下加法之外的算術了:
1.整數(shù)減法:改變數(shù)據(jù)結構闰靴,用補碼代替原碼表示數(shù)字彪笼,這樣做出來的加法不受變化,但是可能有人會覺得A=5,B=3這時候A-B是需要對B取反再加1的會不會增加操作的周期蚂且?其實不用擔心取反只要加反相器配猫,而加1的操作直接在加法器的進位置位1就行啦。所以不會增加操作時間杏死。
2.整數(shù)乘法:依然使用補碼表示數(shù)字泵肄,使用跳轉語句和零標志位判斷結合的新的四個操作碼(JZ,JC,JNZ,JNC)進行加法的多次操作從而模擬乘法。
3.其他算術淑翼,依然可以使用加法器進行模擬腐巢,形成固定算法。
計算機歷史(18-19章)
詳細介紹了人類文明從無到有逐漸發(fā)明了計算機以及工藝改進的歷史玄括,其中出現(xiàn)了一系列杰出人才冯丙,他們不一定是計算機科學家,很多都是基礎領域如數(shù)學遭京、物理胃惜、化學領域的科學家。
主要介紹了兩種典型的微處理器哪雕。因特爾Intel 4004和摩托莫拉Motorola6800蛹疯。
微處理器性能衡量標準:
1.數(shù)據(jù)通路寬度,也就是我們常說的4位热监、8位捺弦、16位處理器。
2.最大時鐘頻率(主頻)孝扛,常用單位HZ,KHZ,MHZ列吼,決定了計算速度。
3.可尋址空間苦始,并不代表RAM的容量寞钥,只是它的尋址能力決定可以裝上多大的RAM。
現(xiàn)代計算機的主要構成(20-25章)
隨著集成電路IC技術的使用陌选,英特爾在1971年制造了第一個微處理器CPU:
1974年Intel8080主頻2MHZ理郑,一條指令位4-18個時鐘周期蹄溉,所以需要2-9微妙。
新增6個寄存器您炉,BCDEHL柒爵,A代表累加器,MOV指令就是對他們的值做操作赚爵。
同時還增加了邏輯運算的功能棉胀。
引入了棧的概念:其實棧也是一段普通的RAM存儲空間,但是它是被獨立劃分出來的冀膝,配合一個特殊的寄存器作為棧指針(SP)使用唁奢。而且棧在物理層表現(xiàn)的也是從下到上堆放,所以棧是會向上溢出覆蓋程序代碼的窝剖。向下SP也會溢出麻掸。
同時為了和外界打交道,8080還引入了中斷的概念赐纱,啟動EI中斷后脊奋,INTE端輸入置1后芯片響應中斷。鍵盤中斷指令RST 4千所,跳轉到0020h處開始處理鍵盤讀取代碼。
現(xiàn)代處理器一般都會自帶一個RAM用作Cache高速緩沖存儲區(qū)蒜埋。
摩爾定律:微處理器中的晶體管數(shù)量每18個月翻一倍淫痰。
為了讓計算機更好地組裝我們引入總線的概念,總線是數(shù)字信號的集合包括:
1.地址信號
2.數(shù)據(jù)輸出信號
3.數(shù)據(jù)輸入信號
4.控制信號
總線還可以為計算機上的不同電路板供電。
操作系統(tǒng):
隨著計算機的使用我們需要解決一下計算機系統(tǒng)的交互性和便捷性的問題了整份。
為了使得程序儲存和數(shù)據(jù)儲存持久化待错,磁盤技術就被引入到計算機系統(tǒng)內(nèi),磁盤不能直接被微機訪問烈评,而是需要先跑一段程序控制內(nèi)存調用磁盤數(shù)據(jù)火俄,然后CPU再來訪問內(nèi)存讀取代碼進行數(shù)據(jù)計算。
接下來解決輸入和顯示的問題讲冠,輸入使用鍵盤瓜客,輸入使用顯示器。
鍵盤是也是一個電子設備竿开,按下一個按鍵就會發(fā)出中斷信號引導CPU處理讀取按鍵的鍵值谱仪。而顯示器就稍微復雜一點,為了使得輸出可讀性高顯示器被設計成點陣的形式否彩,一個大點陣又分為整齊的行列從而劃分出若干單元疯攒。通過顯示適配器(我們常說的顯卡,里面有一塊ROM只讀存儲器可以把字符信息轉換成顯示點陣信息)CPU就可以把需要回顯的信息“打到公屏上”了666列荔。按鍵回顯這個過程需要程序支撐敬尺。
磁盤就像一個文件柜枚尼,管理他是十分麻煩的事情,這時候我們也是需要一個自動化的方法來管理砂吞。
和底層的硬件打交道始終是一件麻煩事情署恍,你需要閱讀特定型號的電子手冊才能知道相應的輸入輸出及使用方法,所以這也是我們想要解決的呜舒。
操作系統(tǒng)就是用來解決人們這些懶惰想法的锭汛,CP/M操作系統(tǒng)包括:
1.基本磁盤操作系統(tǒng)BDOS
2.控制臺命令處理程序CCP
3.應用程序API接口BIOS
在開機通電的時候ROM內(nèi)存儲了一小段引導程序會自舉并引導磁盤加載到內(nèi)存中,從而實現(xiàn)操作系統(tǒng)的加載這個過程叫做引導袭蝗。
到此我們終于實現(xiàn)一臺還可以的計算機了唤殴,當然和現(xiàn)代計算機比他并不夠好,但是現(xiàn)代計算機還是遵循他的原理制造到腥。
以前在學習51單片機時朵逝,我們常常喜歡用定時器中斷來進行延遲操作,但是如果在互聯(lián)網(wǎng)上查詢x86匯編的延遲程序一般都是使用循環(huán)空語句來增加執(zhí)行時間的乡范。一開始我以為PC的CPU是沒有片內(nèi)定時器這個東西的配名。然而其實不是,CPU片內(nèi)定時器和單片機比只會多不會少學習完操作系統(tǒng)我們知道如果要找底層硬件中斷的話需要去查閱BIOS的中斷語句得到:
MOV AH,86H
MOV CX,0x001E
MOV DX,0x8480
INT 15H
//以上代碼執(zhí)行一個2秒的延遲
事實上現(xiàn)代操作系統(tǒng)更為復雜主要包括以下五大功能:
1.進程管理
2.存儲管理
3.設備管理
4.作業(yè)管理
5.文件管理
現(xiàn)在的Bios系統(tǒng)一般都集成在主板的ROM上晋辆,所以當裝好機以后沒有安裝操作系統(tǒng)的電腦也能像古人們一樣進行操作渠脉,而安裝好更高級的操作系統(tǒng)后,你的電腦就成為一臺現(xiàn)代意義上的個人計算機了瓶佳。
因此如果現(xiàn)在我們要組裝一臺計算機芋膘,首先要買一塊電源、一塊主板(主板集成了總線和主板操作系統(tǒng))霸饲、一塊CPU處理器(有些型號集成了顯示適配器为朋,Intel或AMD生產(chǎn))、一塊顯示適配器(顯卡GPU厚脉,英偉達或者AMD生產(chǎn))习寸,一塊或多塊內(nèi)存條(RAM),一個硬盤(磁盤)傻工,以及顯示器和鼠標鍵盤等外設霞溪。最后還需要安裝Windows或者Linux等操作系統(tǒng)。現(xiàn)在你就可以開始正常使用一臺個人電腦了中捆。
打開你的電腦查看配置威鹿,一般顯示適配器有兩張,一張是集成顯卡轨香,一個是獨立顯卡GPU忽你,這就對啦。所以有時候不要太糾結于那種傳統(tǒng)架構下的專有名詞臂容,因為他們很多都是交叉的科雳。
GPU是為了圖像處理而生的根蟹,它在結構上并沒有專門為圖像服務的部件,只是對CPU的結構進行了優(yōu)化與調整糟秘,所以現(xiàn)在GPU不僅可以在圖像處理領域大顯身手简逮,它還被用來科學計算、密碼破解尿赚、數(shù)值分析散庶,海量數(shù)據(jù)處理(排序,Map-Reduce等)凌净,金融分析等需要大規(guī)模并行計算的領域悲龟。
讀后感
人類嘔心瀝血發(fā)明了計算機,為了做人口普查冰寻,為了數(shù)學研究须教,為了在物理上計算原子彈的數(shù)據(jù),計算航天軌道斩芭。而這一切都發(fā)生在我們出生前了轻腺,我們站在了巨人的肩膀上,構建出了現(xiàn)在的生活划乖,你用它來點外賣贬养、看電影或者是做科學研究。計算機的應用不分貴賤琴庵,技術的可獲得性造成了算力的浪費误算,可是哪怕我在這里敲下這些文字(毫無營養(yǎng)毫無樂趣),但他確實幫到了我细卧。
有一個疑惑尉桩,在先賢面前我們都是螻蟻嗎筒占?其實有時候很悲觀地說就是這樣的贪庙,我們應用計算機技術的能力可以說爐火純青,但是即使掌握了如此熟練的理論基礎的前提下讓一個偉大的國家從零開始設計計算機也是相當困難的翰苫。計算機和其他現(xiàn)代工業(yè)品一樣止邮,離開了完整的供應體系和市場全球化都是行不通的,并非我們過于渺小奏窑,而全在于術業(yè)有專攻而已导披。
弗洛伊德認為隨著人類文明的進步反而會增加人類的痛苦,哪怕他存在的時代還沒有計算機埃唯。事實上撩匕,科技發(fā)達文明進步的今天,我們也依舊沒有逃出弗洛伊德的預言墨叛。不過要使自己快樂很簡單止毕,不要被生活束縛了模蜡,計算機始終是服務于人的,你愛讓他干嘛就干嘛只要你有驅使他的本事扁凛。
永遠記住技術是服務于你的忍疾,而不是說到處尋求一種技術只是為了有朝一日變現(xiàn),但是現(xiàn)在的市場形勢就是這樣谨朝,經(jīng)常能看到有人力在抱怨研究生不適應工作卤妒,也經(jīng)常看到他們贊賞部分大專生干活很伶俐字币。雖然我的學歷不高则披,科研水平和工作水準可能都不高,但是我還是希望我的讀者包括未來的我纬朝,要認識到技術是會迭代的收叶,任何沒有準入規(guī)則的行業(yè)只會一直內(nèi)卷下去。
我本人也很反感那些動不動就拿技術棧談話的人共苛,因為任何技術都是在變革的判没,企業(yè)主們永遠只是把你們用做賺錢的機器而已,招一批當前成熟技術棧的人隅茎,過幾年技術革新了就換掉澄峰。企業(yè)不但沒有培養(yǎng)人的意識而且也不給學習的機會,就老拿研究生不適合市場需求開炮辟犀,要是按照他們的邏輯高等數(shù)學學了也是白學俏竞,小學一年級就該去培訓班學Spring框架。
寫到這里如果可以堂竟,我想我自然是不愿意打工的魂毁,因為人做什么都可以活著,但是如果可以從事自己喜歡的事業(yè)那也就勉強再做幾年資本家的奴才吧出嘹,可是要需明白這始終不是什么長遠的頭路席楚。
關于MCU
MCU,單片微型計算機税稼,單片機烦秩。
個人電腦CPU基本被Intel壟斷了,同樣的因特爾也有涉及單片機市場郎仆,比如80C51和89C51就是他們家設計的只祠,并且十分便宜一般在兩塊錢到五塊錢不等。
STM32單片機則是ST(意法半導體)公司使用arm公司的cortex-M3為核心生產(chǎn)的32bit系列的單片機扰肌,他的內(nèi)部資源(寄存器和外設功能)較8051抛寝、AVR和PIC都要多的多,基本上接近于計算機的CPU了,適用于手機盗舰、路由器等等猴凹。一塊差不多十塊錢左右。
MCU和CPU的主要組成部分其實都差不多岭皂,無非是運算器郊霎、控制器、存儲寄存器爷绘、高速緩沖區(qū)等基礎部件組合而成的书劝。不同之處在于它們的硬件電路實現(xiàn)不同,個數(shù)不同土至,功耗不同购对,計算能力不同,但都提供相同的基本功能陶因。俗話說麻雀雖小五臟俱全骡苞,MCU可能就是這樣的存在吧,因為他自己就是一臺電腦楷扬,不像CPU還要依賴別人才能組成一臺電腦解幽。可是這兩個電腦也不是一個維度的烘苹,他們的應用場景和使用方法還是有很大區(qū)別的躲株。
思考1:關于JVM虛擬機
JAVA程序運行在JVM虛擬機內(nèi)部,JVM跑在操作系統(tǒng)上镣衡。那么虛擬機和真正的計算機有什么聯(lián)系和區(qū)別呢霜定?
思考2:關于線程、進程廊鸥,多任務
操作系統(tǒng)解決了多任務的問題望浩,那么他是怎么解決的,常說的多進程惰说、多線程有什么區(qū)別磨德?
2021年3月31日,回來回答這個問題了助被,雖然還是查資料才懂剖张。
概念:
進程(Process) 是計算機中的程序關于某數(shù)據(jù)集合上的一次運行活動切诀,是系統(tǒng)進行資源分配和調度的基本單位揩环,是操作系統(tǒng)結構的基礎。 在當代面向線程設計的計算機結構中幅虑,進程是線程的容器丰滑。程序是指令、數(shù)據(jù)及其組織形式的描述,進程是程序的實體褒墨。是計算機中的程序關于某數(shù)據(jù)集合上的一次運行活動炫刷,是系統(tǒng)進行資源分配和調度的基本單位,是操作系統(tǒng)結構的基礎郁妈。程序是指令浑玛、數(shù)據(jù)及其組織形式的描述,進程是程序的實體噩咪。
線程(thread) 是操作系統(tǒng)能夠進行運算調度的最小單位顾彰。它被包含在進程之中,是進程中的實際運作單位胃碾。一條線程指的是進程中一個單一順序的控制流涨享,一個進程中可以并發(fā)多個線程,每條線程并行執(zhí)行不同的任務仆百。
簡單地理解:
在計算機中厕隧,一個程序是一組指令的有序集合。
任務是抽象的,是一個術語,指由軟件完成的一個活動俄周,因此認為可以是線程也可以是進程(但是網(wǎng)上說法比較多吁讨,說任務就等于進程的人也有)。所謂多任務就是計算機看起來好像在一時間段內(nèi)交替進行多個任務(進程或者線程)峦朗。
一個程序的開啟就意味著一個或者多個進程被打開(由于鄙人不善編程只是一個JAVA的API愛好者挡爵,所以不知道怎么用一個程序啟動多個進程,因為JAVA是啟動虛擬機完成任務的所以和操作系統(tǒng)有關)甚垦。因此茶鹃,我們還是只討論線程和進程的關系吧。
一般來說艰亮,進程是表示資源分配的基本單位闭翩,又是調度運行的基本單位。例如迄埃,用戶運行自己的程序疗韵,系統(tǒng)就創(chuàng)建一個進程,并為它分配資源侄非,包括各種表格蕉汪、內(nèi)存空間、磁盤空間逞怨、I/O設備等者疤。然后,把該進程放人進程的就緒隊列叠赦。進程調度程序選中它驹马,為它分配CPU以及其它有關資源,該進程才真正運行。所以糯累,進程是系統(tǒng)中的并發(fā)執(zhí)行的單位算利。
線程是進程中執(zhí)行運算的最小單位。這時候你啟動一個父線程讓他啟動三個子線程(不管他們同步不同步)泳姐,那么各線程共享相同的代碼和全局數(shù)據(jù),但各有其自己的堆棧效拭。這塊全局數(shù)據(jù)的存放區(qū)就是共享內(nèi)存。而進程和進程間的通訊就比較復雜了...我還不會不展開了