【OS学习笔记】一 处理器、内存和指令
學(xué)習(xí)交流加
- 個(gè)人qq:
1126137994 - 個(gè)人微信:
liu1126137994 - 學(xué)習(xí)交流資源分享qq群:
962535112
我們已經(jīng)知道,處理器是一臺(tái)電子計(jì)算機(jī)的核心,它會(huì)在振蕩器脈沖的激勵(lì)下,從內(nèi)存中獲取指令,并發(fā)起一系列由該指令所定義的操作。當(dāng)這些操作結(jié)束之后,它接著再取下一條指令。通常情況下,這個(gè)過程是連續(xù)不斷、循環(huán)往復(fù)的。
文章目錄
- 1、寄存器和算數(shù)邏輯部件
- 2、內(nèi)存儲(chǔ)器
- 3、指令和指令集
- 4、Intel 8086處理器
- 4.1、 8086的通用寄存器
- 4.2、 程序的重定位問題
- 4.3、 內(nèi)存分段機(jī)制
- 4.4 、8086的內(nèi)存分段機(jī)制
- 4.5 、8086 處理器內(nèi)部組成框圖
- 5、 總結(jié)
1、寄存器和算數(shù)邏輯部件
電子計(jì)算機(jī)能能做很多事情。計(jì)算天氣預(yù)報(bào),看電影,聽音樂,上網(wǎng)等,實(shí)際上都是以數(shù)學(xué)計(jì)算為基礎(chǔ)。它之所以能夠計(jì)算,是因?yàn)樗厥獾脑O(shè)計(jì)。想要了解計(jì)算機(jī)為什么能夠自動(dòng)計(jì)算,請(qǐng)去閱讀書籍《穿越計(jì)算機(jī)的迷霧》。本片文章主要講解處理器的簡單功能。
如圖是一個(gè)處理器:
在處理器的周圍,有大量的引腳,這些引腳可以接受從外面來的電信號(hào)或者向外發(fā)送電信號(hào)(與外設(shè)進(jìn)行信號(hào)的交互)。有很多引腳是復(fù)用的,假如現(xiàn)在我們要進(jìn)行加法運(yùn)算,我們就需要重復(fù)使用某一些引腳來依次將加數(shù)與被加數(shù)送入。一旦被加數(shù)被送入處理器,代表這個(gè)二進(jìn)制數(shù)字的一組電信號(hào)就會(huì)出現(xiàn)在與該引腳相連的內(nèi)部線路上(我們稱這個(gè)內(nèi)部線路為內(nèi)部總線)。這是一組高低電平的組合,代表著二進(jìn)制數(shù)中的每一位。當(dāng)被加數(shù)被送進(jìn)來了,接下來就要將加數(shù)送進(jìn)來,但是此時(shí)內(nèi)部總線上有被加數(shù),所以處理器內(nèi)部需要有一個(gè)電路來將被加數(shù)“鎖存”。這個(gè)將被加數(shù)鎖存的電路就是寄存器。它是一個(gè)存儲(chǔ)器件。
同樣,加數(shù)也要鎖存進(jìn)另一個(gè)寄存器。如圖中RA與RB分別鎖存的是被加數(shù)與加數(shù)。此后,被加數(shù)與加數(shù)將不再受處理器的內(nèi)部總線的影響。寄存器是雙向器件,它會(huì)將它鎖存的數(shù),在另一端產(chǎn)生一模一樣的電信號(hào)(注意此時(shí)寄存器中依然鎖存著之前的電信號(hào),它只是在另一端產(chǎn)生一個(gè)一模一樣的電信號(hào)),傳送給相應(yīng)的算數(shù)邏輯部件(ALU)進(jìn)行計(jì)算。算數(shù)邏輯部件(ALU)計(jì)算出結(jié)果后,將結(jié)果送出,給另一個(gè)寄存器RC鎖存,稍后再將RC中的內(nèi)容通過內(nèi)部總線送到處理器外部,或者再次送回RA RB寄存器進(jìn)行其他計(jì)算。
那么,處理器是如何知道什么時(shí)候該干什么,各個(gè)部件在各個(gè)時(shí)間點(diǎn)該干什么,以及哪些部件在哪些時(shí)候使用內(nèi)部總線以避免總線沖突呢?這些實(shí)際上都是由處理器內(nèi)部的一個(gè)控制器控制的(圖中沒有畫出)。
處理器總是繁忙的,所有數(shù)據(jù)都只能在寄存器中寄存一會(huì),就必須被送往別處。早期的寄存器只能存儲(chǔ)4比特、8比特或者16比特,分別叫做4位寄存器,8位寄存器和16位寄存器。現(xiàn)在的處理器大多是32位和64位的。
2、內(nèi)存儲(chǔ)器
上一節(jié)我們知道,處理器的計(jì)算過程實(shí)際上是借助于寄存器和算數(shù)邏輯部件進(jìn)行的。那么計(jì)算的數(shù)據(jù)是從哪里來的呢?它是從一個(gè)可以保存很多數(shù)字的電路,叫做存儲(chǔ)器。存儲(chǔ)器的種類很多,我們常見的U盤,硬盤,磁盤,內(nèi)存條,甚至寄存器等都是存儲(chǔ)器。
我們這里主要說內(nèi)存條。由于它通常是和處理器直接相連的,所以叫內(nèi)存儲(chǔ)器或者主存儲(chǔ)器。又或者內(nèi)存或者主存。和寄存器不同,內(nèi)存用于保存更多的比特。對(duì)應(yīng)用的最多的個(gè)人計(jì)算機(jī)來說,內(nèi)存是按字節(jié)來組織的,單次訪問的最小單位是1字節(jié),這是最基本的存儲(chǔ)單元。如下圖所示是一個(gè)內(nèi)存和內(nèi)存訪問示意圖:
內(nèi)存中的每一個(gè)字節(jié)都對(duì)應(yīng)著一個(gè)地址。從0地址開始,由于上面的內(nèi)存是65536字節(jié),所以該內(nèi)存的最后一個(gè)字節(jié)是FFFF(都是用的十六進(jìn)制表示的)。為了訪問一個(gè)內(nèi)存,處理器需要給出一個(gè)地址。同時(shí)訪問內(nèi)存是什么方式?讀方式或者寫方式,所以處理器需要有一個(gè)讀寫控制。如果是寫數(shù)據(jù),處理器還需要有一個(gè)數(shù)據(jù)傳輸?shù)目刂啤W詈?#xff0c;處理器單次訪問內(nèi)存時(shí),是以字節(jié)為單位訪問還是以字為單位訪問等,需要有一個(gè)字長控制來告知。
3、指令和指令集
從一開始設(shè)計(jì)處理器,就是想讓它自動(dòng)工作,另外,還需要提供一種機(jī)制,來允許程序員決定進(jìn)行何種工作。處理器的設(shè)計(jì)者用某些數(shù)來表示該處理器該做什么,這些數(shù),我們稱為指令或者叫機(jī)器指令。
下面給個(gè)實(shí)際例子來分析指令在內(nèi)存中的布局:
假設(shè)現(xiàn)在我們的處理器是從內(nèi)存的0000地址開始取指令(實(shí)際上肯定不是從0地址開始,這里只是假設(shè))。第一條指令B8 5D 00,該指令的意思是將立即數(shù)005D傳送到RA寄存器,它具有一個(gè)字節(jié)的操作碼B8。由此我們可以看出簡單的一個(gè)B8 5D 00指令,是一個(gè)傳送指令,且該指令將兩個(gè)字節(jié)(005D)傳送到RA寄存器,并且由于下一條指令的地址是在0003字節(jié)處,所以該指令肯定還知道它自己是一條3字節(jié)指令,以便下一次處理器可以直接去到0003字節(jié)處去取指令。
對(duì)于一些復(fù)雜的指令,一個(gè)字節(jié)的操作碼肯定不夠用,所以第二條指令8B 1E 3F 00的指令操作碼是兩字節(jié)8B 1E。
同時(shí)我們注意到上述前兩條指令中,第一條指令是將一個(gè)數(shù)005D直接傳送到寄存器,第二條指令,是需要從另外一個(gè)地址(003F)先取出數(shù)據(jù),然后再將數(shù)據(jù)傳送到寄存器。第一種的操作數(shù)005D我們稱為立即數(shù)(表示可以立即將數(shù)傳送而不需要再去另外一個(gè)地址取數(shù)據(jù))。
由以上分析,我們很容易知道,上述的幾條指令,首先將兩個(gè)數(shù)放到寄存器中去運(yùn)算,然后運(yùn)算結(jié)果放到其中一個(gè)寄存器中,最終還需要將運(yùn)算結(jié)果再傳回到內(nèi)存中以便該結(jié)果作為其他用處時(shí)處理器好可以從內(nèi)存中得到計(jì)算結(jié)果。最后F4指令停機(jī)。
指令和非指令的二進(jìn)制數(shù)據(jù)是一模一樣的,在組成內(nèi)存的電路中,都是一些高低電平的組合。因?yàn)樘幚砥魇前错樞蛉≈噶?#xff0c;并加以執(zhí)行的,這樣的話,如果指令和數(shù)據(jù)存放在一起,處理器很容易將數(shù)據(jù)的二進(jìn)制當(dāng)成指令,從而導(dǎo)致錯(cuò)誤。所以我們需要將指令與數(shù)據(jù)分開存放。分別存放在不同的區(qū)域。存放指令的區(qū)域叫做代碼區(qū),存放數(shù)據(jù)的區(qū)域叫做數(shù)據(jù)區(qū)(這就是為什么進(jìn)程的虛擬地址空間中代碼和數(shù)據(jù)區(qū)分開的原因)。
一個(gè)處理器能夠識(shí)別的指令的集合,稱為指令集。
4、Intel 8086處理器
要想學(xué)好編程,就必須要懂底層原理。但是想要徹底學(xué)好底層,就要把匯編學(xué)好。想要學(xué)好匯編,不得不先學(xué)好針對(duì)8086的匯編技術(shù)。
4.1、 8086的通用寄存器
8086處理器內(nèi)部有8個(gè)16位寄存器。分別被命名為:AX,BX,CX,DX,SI,DI,BP,SP。通用的意思是他們中大部分可以根據(jù)需要用于多種目的。他們的用處,將在后面的文章逐漸給出。
下圖是幾個(gè)寄存器:
可以看到,有介個(gè)寄存器,AX,BX,CX,DX,又可以分為兩個(gè)8位的寄存器來使用。在后面文章中,我們會(huì)看到具體的應(yīng)用。
4.2、 程序的重定位問題
我們知道,處理器是自動(dòng)取指令和執(zhí)行指令的,只要每條指令都正確無誤,它就能準(zhǔn)確的知道下一條指令的地址。所以,指令必須集中在一起,形成一個(gè)段,叫做代碼段。
為了做某件事而編寫的指令,形成我們所知道的程序。程序中肯定需要操作大量的數(shù)據(jù),這大量的數(shù)據(jù)也應(yīng)該集中在一起,位于內(nèi)存中的某個(gè)地方,叫做數(shù)據(jù)段。
段在內(nèi)存中的位置并不重要,因?yàn)樘幚砥魇强煽氐?#xff0c;我們可以讓處理器在內(nèi)存中的任何一個(gè)位置開始取指令并加以執(zhí)行。
下面看一個(gè)圖示:
假設(shè)上面是一個(gè)程序片段在內(nèi)存中的位置,相關(guān)指令的用處已經(jīng)在圖中表明。這里不再贅述。但是現(xiàn)在有一個(gè)問題,就是我們寫的程序(不管是C語言還是C++語言或者Java語言),最終要運(yùn)行在內(nèi)存中的位置,是無法確定的。因?yàn)槟阆胍幌?#xff0c;本身你的電腦中有各種程序在跑了,有qq程序在跑,微信程序在跑,或者還有微博等在跑,他們可能把你的內(nèi)存都占完了,當(dāng)你想運(yùn)行你寫的程序的時(shí)候,你的程序本想從0100H處開始存放代碼段,但是可能這個(gè)時(shí)候0100H處有其他程序的代碼或者指令在運(yùn)行,此時(shí)你的程序只能去另一個(gè)位置存放你的代碼和數(shù)據(jù),假設(shè)你的代碼下一次運(yùn)行的時(shí)候代碼段和數(shù)據(jù)段在如下位置:
此時(shí)你的程序的代數(shù)據(jù)段在內(nèi)存的位置為1000H處,但是你會(huì)發(fā)現(xiàn),你的代碼段的第一條指令,還是將地址單元0100H處的內(nèi)容傳送到AX寄存器中。但是!!!此時(shí)0100H處的內(nèi)容,并不是我們想要的內(nèi)容。
產(chǎn)生這種情況的原因就是我們?cè)诔绦蛑惺褂玫氖墙^對(duì)內(nèi)存地址。這樣的程序是無法重新定位的。所以我們需要使用另一種方式訪問內(nèi)存:相對(duì)地址或者叫做邏輯地址。在任何時(shí)候,程序的重定位都是非常棘手的事情。在8086處理器中,這個(gè)問題得到解決。它使用了分段機(jī)制。
4.3、 內(nèi)存分段機(jī)制
在內(nèi)存分段中,段,是很多個(gè)連續(xù)的字節(jié)組成的。如圖:
上圖有一個(gè)7個(gè)字節(jié)的段。段的起始地址為A532。那么段中的地址從第一個(gè)字節(jié)開始,他們的地址此時(shí)就是段內(nèi)的偏移地址(0000,0001,0002…)。而他們的實(shí)際的物理地址,又恰好等于段地址加上段內(nèi)的偏移地址。可以用“段地址:偏移地址”,來表示段中的每一個(gè)字節(jié)的地址。
為了在硬件一級(jí)提供對(duì)“段地址:偏移地址”的支持。處理器至少要提供兩個(gè)段寄存器,分別是代碼段寄存器CS,數(shù)據(jù)段寄存器DS。
對(duì)代碼段CS內(nèi)容的改變,將導(dǎo)致處理器從新的代碼段開始執(zhí)行。當(dāng)然,在訪問數(shù)據(jù)之前,也是必須要提前設(shè)置好數(shù)據(jù)段寄存器DS的,使DS之指向數(shù)據(jù)段。
很重要的一點(diǎn)是,當(dāng)處理器取指令執(zhí)行指令的時(shí)候,它是把指令中指定的內(nèi)存地址看成是段內(nèi)偏移地址的。而不是內(nèi)存的物理地址。那么當(dāng)處理器遇到一條訪問內(nèi)存的指令時(shí),它就會(huì)將DS中的數(shù)據(jù)段起始地址加上指令中提供的段內(nèi)偏移地址得到訪問內(nèi)存所需要的物理地址的。
如下圖所示:
代碼段地址為1020H,數(shù)據(jù)段地址為1000H,在代碼段中有一條指令:A1 02 00,它的功能是將地址0002H處的的一個(gè)字傳送到寄存器AX。在這里處理器將0002H看成是段內(nèi)偏移地址,段地址在DS中,應(yīng)該在執(zhí)行這條指令之前就已經(jīng)用別的地址將數(shù)據(jù)段地址傳送到DS寄存器中了。當(dāng)處理器執(zhí)行到指令A(yù)1 02 00時(shí),處理器會(huì)將DS中的內(nèi)容和指令中指定的便宜地址相加,得到內(nèi)存中的一個(gè)物理地址,這個(gè)物理地址就是處理器要去訪問的內(nèi)存地址,就可以從該地址獲取一個(gè)字:00A0H。
如果下一次執(zhí)行該程序,代碼段和數(shù)據(jù)段發(fā)生變化,只需要將程序的代碼段地址和數(shù)據(jù)段地址分別傳送到CS和DS就可以正常的執(zhí)行程序了。
4.4 、8086的內(nèi)存分段機(jī)制
前面講了如何從邏輯地址轉(zhuǎn)換到物理地址,以使得程序的運(yùn)行和它在內(nèi)存中的位置是無關(guān)的。上述策略在很多處理器上應(yīng)用得到了支持。但是在8086處理器上,由于8086處理器是16位處理器,如果按照正常計(jì)算,給它提供16根地址線的話,那么8086處理器就只能用于尋址最多64KB的內(nèi)存空間(65536字節(jié)=2的15次方+1)。在當(dāng)時(shí)的年代64KB的內(nèi)存還是不夠的。所以8086處理器就將16根地址線擴(kuò)展到20根地址線。從而使得可尋址的空間變?yōu)?M(16*64KB)。
但是有一個(gè)問題就是16位的段地址加上16位的段內(nèi)偏移地址,還是16位的,并不是20位的。所以有一個(gè)解決辦法就是在計(jì)算內(nèi)存的物理地址時(shí),先將段地址先左移4位,然后加上段內(nèi)偏移地址,這樣就可以得到20位的物理地址,就可以將整個(gè)1M的地址空間表示完全。
8086在進(jìn)行分段時(shí),并不是每一個(gè)地址都可以作為段地址,地址必須是16的倍數(shù),才能作為段地址。
如下圖,是其中的一種情況,我們從0地址開始分段,每段16字節(jié)(從任何地址只要這個(gè)地址是16的倍數(shù),都可以作為段地址,每一個(gè)段內(nèi)最低有16字節(jié)(可以分為65536個(gè)段)的內(nèi)存,最高有65536(可以分為16個(gè)段)個(gè)字節(jié)的內(nèi)存)
4.5 、8086 處理器內(nèi)部組成框圖
最后我們?cè)賮砜匆幌?086處理器內(nèi)部組成框圖:
上圖中,我們知道8086內(nèi)部有8個(gè)16位通用寄存器,分別為AX,BX,CX,DX,SI,DI,BP,SP。ALU是算數(shù)邏輯部件,用于算數(shù)邏輯運(yùn)算或者數(shù)據(jù)傳送。標(biāo)志寄存器是用于控制各種依賴于標(biāo)志位的標(biāo)志來進(jìn)行相應(yīng)的指令執(zhí)行的,這個(gè)可以等到以后的文章中進(jìn)行詳細(xì)的說明,目前不需要理解。處理器可以自動(dòng)執(zhí)行,依賴于控制器的控制。
指令隊(duì)列緩沖器,又名:指令預(yù)取隊(duì)列。什么意思呢?就是當(dāng)你的CPU在忙于做其他事情(一般是指執(zhí)行那些不需要去內(nèi)存中取的指令)而并沒有去內(nèi)存中取指令執(zhí)行時(shí),此時(shí)指令隊(duì)列緩沖器(指令預(yù)取隊(duì)列)就會(huì)去內(nèi)存中取出6個(gè)字節(jié)的指令放到指令隊(duì)列緩沖器,那么當(dāng)CPU該執(zhí)行內(nèi)存中的指令時(shí),它就會(huì)就近向指令隊(duì)列緩沖器中去取指令,這樣的話就會(huì)比去內(nèi)存中取指令要快很多,畢竟內(nèi)存還是通過外部總線與內(nèi)存條相連接的。
CS是代碼段寄存器。DS是數(shù)據(jù)段寄存器。SS是棧段寄存器(很重要,以后會(huì)講)。ES是額外的段寄存器,它的用處相當(dāng)于補(bǔ)充段寄存器,當(dāng)你的DS在使用時(shí),但是你還要訪問另一個(gè)數(shù)據(jù)段,那么此時(shí)就可以使用ES寄存器(后面的文章中我們就用ES寄存器指向顯卡的內(nèi)存區(qū)域,用來尋址顯存,從而控制顯卡)。IP寄存器,是存代碼段的段內(nèi)偏移地址的。那么指令的地址此時(shí)就可以用“CS:IP”來表示。
上面的與總線控制邏輯相連的16位總線,實(shí)際上是16位的數(shù)據(jù)總線與20位的地址總線的低16位復(fù)用的。20位代表的是20位的地址總線是(當(dāng)然,低16位是與數(shù)據(jù)總線復(fù)用的)。
5、 總結(jié)
想要寫出優(yōu)秀的應(yīng)用程序,就必須對(duì)系統(tǒng)編程有深入的理解。想要對(duì)系統(tǒng)編程有一定的理解,就必須理解操作系統(tǒng)原理。我選擇從X86匯編開始學(xué)習(xí),逐步深入理解操作系統(tǒng)與計(jì)算機(jī)系統(tǒng)之間的關(guān)系。
本片文章可以讓我們學(xué)會(huì)
- 寄存器與算數(shù)邏輯部件的簡單關(guān)系
- 內(nèi)存儲(chǔ)器
- 指令和指令集
- 程序的重定位問題
- 處理器與內(nèi)存之間的關(guān)系
- 內(nèi)存分段機(jī)制
學(xué)習(xí)探討加
qq:1126137994
微信:liu1126137994
總結(jié)
以上是生活随笔為你收集整理的【OS学习笔记】一 处理器、内存和指令的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 假如生活欺骗了你
- 下一篇: 全套思源黑体合集(含ttf/ttc版/行