關(guān)于計算機(jī)的最小存儲單位
有一篇帖子介紹的非常好
為什么計算機(jī)最小的存儲單位是字節(jié)?而最小到的傳輸單位是bit?
我來總結(jié)一下,計算機(jī)中所有的一切確實都是以2進(jìn)制存儲的,但是在實際數(shù)據(jù)存儲中卻是以字節(jié)為單位的,因為1個位只有兩個狀態(tài),并不能表示現(xiàn)實生活中一個完整的信息。
比如ASCII碼的一個字符小寫字母a,這是一個相對人類有用的信息
它在計算機(jī)中是以是8個bit存儲的,也就是1個字節(jié),1個位的0和1兩個狀態(tài)并不能表示字符a(ASCII碼表對應(yīng)的二進(jìn)制為0110 0001)
所以人們在設(shè)計計算機(jī)存儲的時候還是要以字節(jié)為單位表示一個對人類相對完整的信息
一個位,也就是一個bit,是表示信息的最小單位。只有0和1兩種狀態(tài),對應(yīng)計算機(jī)電路中的高電平和低電平。在這個維度上,只能表示
一些簡單的信息,也可以當(dāng)做flag來使用。
ps:順便噴一下這篇帖子中的評論P(yáng)hoenixJ的評論:
一派胡言。 知道標(biāo)識位么? 1bit是可以表示信息的。
這傻吊明顯沒有仔細(xì)閱讀帖子,博主說的是用字節(jié)表示一個相對有用的信息,你都沒有好好讀人家帖子上來就噴什么一派胡言,恩,那我站在道德的角度上噴你是個loser你高興?
我一直相信程序員是用自己的技術(shù)使人們和自己的生活變得更加美好,這也就要求從業(yè)者自己首先要具備一定的素質(zhì),你連最基本的尊重別人都做不到還寫你mmp的代碼~
關(guān)于存儲器
存儲器是按字節(jié)編址的
這里的存儲器就是指我們的內(nèi)存(內(nèi)存條)
廣義上的存儲器還有硬盤以及別的移動存儲設(shè)備
咱們所有的數(shù)據(jù)、代碼、指令最終都會轉(zhuǎn)變?yōu)槎M(jìn)制存儲在內(nèi)存中
即使用匯編語言寫出來的指令最終也都是存儲在內(nèi)存中的一堆堆二進(jìn)制
存儲單元

如上圖所示
8086的地址總線是20位的
在二進(jìn)制下是00000000000000000000 - 11111111111111111111
00000000000000000000 對應(yīng)的十進(jìn)制是0
11111111111111111111 對應(yīng)的十進(jìn)制是1048575
在16進(jìn)制下是00000H(0x00000) - FFFFFH(0xFFFFF)
00000H 對應(yīng)的十進(jìn)制是0
FFFFFH 對應(yīng)的十進(jìn)制是1048575
也就是說地址總線總共可以尋找到1048576個字節(jié)(注意,這里是字節(jié)?。。。。。。。。?br> 等于1024KB個字節(jié),也就是1MB個字節(jié)
也就是說地址總線只能尋找到1048576個字節(jié),1M字節(jié)的內(nèi)存,你即使插上個8G的內(nèi)存也并沒有什么卵用
ps:話說回來以后一定要注意大B和小b,不注意細(xì)節(jié)的話要向我一樣找資料找好久。。。
數(shù)據(jù)存儲是以字節(jié)為單位的
那么一個字節(jié)就表示一個存儲單元
也就是說物理地址00000H - 00001H之間的就是一個存儲單元
存儲單元中的數(shù)據(jù)存儲
大部分?jǐn)?shù)據(jù)存儲是以字節(jié)為單位表示的
也就是說這種數(shù)據(jù)占一個存儲單元
也有的數(shù)據(jù)是以字為單位表示的,這樣的數(shù)據(jù)在存儲器中占有連續(xù)的兩個存儲單元
比如一個以字為單位的數(shù)據(jù)1234H,也就是兩個字節(jié)16位,它存儲的時候會占用兩個連續(xù)的數(shù)據(jù)單元00000H和00001H。
計算機(jī)的運算存儲規(guī)則如下:
低位字節(jié)存入低地址,也就是34H存入00000H
高位字節(jié)存入高地址,也就是12H存入00001H
還有的數(shù)據(jù)是以雙字位單位表示的,這樣的數(shù)據(jù)數(shù)據(jù)在存儲器中占有連續(xù)的兩個字,也就是連續(xù)的四個存儲單元
以字節(jié)為單位的數(shù)據(jù)就是用它本身的地址表示
而以字為單位的數(shù)據(jù)則是用它的低位地址表示
也就是說同一個地址,既可以看做字節(jié)單元地址,也可以看做字單元地址
邏輯地址與物理地址
物理地址是存儲器的絕對地址(在8086中為20位的實際地址)
范圍用16進(jìn)制表示為00000H - FFFFFH
是由CPU訪問存儲器的時候由地址總線發(fā)出的地址
邏輯地址是由段基址和段內(nèi)偏移地址組成的地址
段基址和段內(nèi)偏移地址都是16位的無符號二進(jìn)制數(shù),在程序設(shè)計的時候使用
- 比如一個段基址的物理地址是00000H(5位16進(jìn)制為20位二進(jìn)制)因為CPU中的寄存器是16位的,也就是說只可以裝下16位的地址,那么便舍棄最后一位(在8086中段基址的16進(jìn)制最后一位都是0)
就變成了0000H(4位16進(jìn)制為16位二進(jìn)制)- 段內(nèi)偏移地址不存在去掉位數(shù)的情況,它本身就是一個16進(jìn)制的數(shù),是址相對于當(dāng)前的段基址的偏移地址。
注意偏移地址本身就是16位的!?。?/strong>
物理地址的補(bǔ)充
尋址空間是按照處理器的地址線個數(shù)定的,因為8086的地址線只有20根,因此它的尋址能力只有2^20字節(jié) = 1MB。i386結(jié)構(gòu)的處理器都是可以按照字節(jié)編址,每個內(nèi)存單元的地址,不稱為物理地址而是線性地址,線性地址通過CPU內(nèi)存管理單元(MMU)來進(jìn)行轉(zhuǎn)換,因為在8086上只有段管理機(jī)制,因此此時線性地址等價于物理地址。
到32處理器,cpu地址線擁有32根,尋址能力達(dá)到4GB,而P4處理器的地址線則擁有35根,可以尋址更大的空間。但是實際內(nèi)存達(dá)不到CPU的尋址空間大小,此時CPU的MMU就需要對線性地址進(jìn)行向物理地址的轉(zhuǎn)化,此時線性地址就和物理地址不一樣了。
決定一個內(nèi)存單元的物理地址時需要根據(jù)當(dāng)前的內(nèi)存管理方式進(jìn)行計算,首先根據(jù)虛擬地址計算得到線性地址,然后根據(jù)分頁機(jī)制是否打開,如果沒有使用分頁機(jī)制,線性地址就是物理地址,如果打開分頁機(jī)制則根據(jù)頁目錄和頁表項來計算得物理地址
ps:摘抄自網(wǎng)絡(luò)
在8086中咱說的物理地址實際上叫線性地址,但是為了簡化流程,下文將線性地址以物理地址代替
內(nèi)存分段
這里所說的都是邏輯地址哦~
也可以說講的是邏輯地址是怎么由來的
8086CPU外部地址總線是20位的,最大可尋址內(nèi)存空間為1MB。而8086的寄存器都是16位的。
用16位的地址尋址1MB空間是不可能的。所以就要把內(nèi)存分段。
分為幾個段基址,段基址下又有段內(nèi)偏移地址
- CPU將內(nèi)存分為四個大段:
設(shè)置4個16位的段寄存器,用于管理4種段。
CS是代碼段,DS是數(shù)據(jù)段,SS是堆棧段,ES是附加段。
把內(nèi)存分段后,每一個段就有一個段基址。
因為段寄存器都是16位的,所以它們保存的是這個段基址的高16位(段基址的物理地址是20位),這個16位的地址左移四位(后面加上4個0)就可推回20位的段基址物理地址,這是CPU中的地址加法器的工作,下面講CPU的時候會講到。- 每個段內(nèi)又有段內(nèi)偏移地址,段內(nèi)偏移地址最大為64KB。
ps:段內(nèi)偏移地址最大為64K字節(jié),因為寄存器是16位的,2的16次方為65536,每個表示一個字節(jié),也就是65536個字節(jié),除1024,也就是64KB個字節(jié)
其實如果段內(nèi)偏移地址最大是64KB的話,那么1MB字節(jié)的內(nèi)存可以分為16個段,16*64KB = 1MB。
但是這是我們根據(jù)具體情況劃分的。
王爽的《匯編語言》(第三版 )中說內(nèi)存并沒有被分成一個一個段,段的劃分來自于CPU
所以我們只需要記住如下總結(jié)就好了:
- 段的劃分來自CPU。
- 內(nèi)存從大體上分為四個段,每個段的物理地址是20位的,但是編寫程序的時候一般使用該段的邏輯地址,也就是將最后一位16進(jìn)制的0舍棄,得到一個4位的16進(jìn)制地址。
- 每個段內(nèi)偏移地址最大為64KB(因為16位寄存器只能存放64KB的地址)
物理地址的計算方法
把邏輯段地址左移4位二進(jìn)制,然后再加上邏輯段內(nèi)偏移偏移地址,就可以尋找到當(dāng)前要執(zhí)行的指令(或是當(dāng)前要讀寫的數(shù)據(jù))所在的物理內(nèi)存地址
0000 (16進(jìn)制邏輯段地址左移四位,也就是16進(jìn)制左移1位)
+ 0001 (16進(jìn)制邏輯段內(nèi)偏移地址)
-----------
00001 (16進(jìn)制物理地址,也就是20位的二進(jìn)制物理地址)
說明
下列所有關(guān)于CPU的描述中使用的段基址以及段內(nèi)偏移地址都是以邏輯地址的形式進(jìn)行說明的
因為寄存器中存放的全部都是邏輯地址
邏輯地址與物理地址的轉(zhuǎn)變由CPU中的BIU部分(總線接口部件)中的地址加法器完成
關(guān)于CPU的執(zhí)行
計算機(jī)去執(zhí)行一條指令的時候并不是直接拿來執(zhí)行的
而是要先去根據(jù)這個指令的二進(jìn)制所存儲的地址去取得這個指令的二進(jìn)制,然后解譯,執(zhí)行
CPU的內(nèi)部組成
運算器
對數(shù)據(jù)進(jìn)行算數(shù)和邏輯運算。這些功能由算數(shù)邏輯單元(ALU arithmetic and logic unit)來實現(xiàn)
寄存器組
8086 CPU 中寄存器總共為 14 個,且均為 16 位 。
即 AX,BX,CX,DX,SP,BP,SI,DI,IP,F(xiàn)LAG,CS,DS,SS,ES 共 14 個。
cpu中的寄存器的數(shù)量對cpu運行速度的影響很大
寄存器組可以存放的類型如下:
- 數(shù)據(jù)(數(shù)據(jù)寄存器)
- 地址 (地址寄存器)
- 控制信息 (控制寄存器)
- 狀態(tài)信息 (狀態(tài)標(biāo)志寄存器)
控制器
控制器是指揮與控制計算機(jī)各功能協(xié)同工作,自動執(zhí)行計算機(jī)程序的部件。
CPU的編程結(jié)構(gòu)
編程結(jié)構(gòu)呢,就是從程序員和使用者的角度看到的結(jié)構(gòu),就像思維導(dǎo)圖一樣,是為了便于我們分析和理解,區(qū)別于真正的物理結(jié)構(gòu)。
那么8086CPU的編程結(jié)構(gòu)如下:

編程結(jié)構(gòu)下的CPU
在編程結(jié)構(gòu)下,按功能可將8086CPU分為兩個部分:
- 總線結(jié)構(gòu)部件BIU(Bus Interface Unit)
- 執(zhí)行部件EU(Execution Unit)
總線接口部件BIU的組成
總線接口單元BIU主要負(fù)責(zé)與外界聯(lián)系,也就是使CPU具有與片外存儲器或者I/O接口電路進(jìn)行數(shù)據(jù)交換的能力。
準(zhǔn)確來說它有如下功能:
- 從內(nèi)存中取指令送到指令隊列
- 在CPU執(zhí)行指令時,配合EU從指定的內(nèi)存單元或I/O端口讀取數(shù)據(jù),再將數(shù)據(jù)傳送給EU,由EU去執(zhí)行。
- 把EU執(zhí)行的結(jié)果傳送到指定的內(nèi)存單元或I/O端口
它由如下幾部分組成:
4個段地址寄存器(16位)
4個段地址寄存器中分別存放了其對應(yīng)功能內(nèi)存段的基址
CS(Code Segment)
段寄存器CS指向存放程序的內(nèi)存段,IP是用來存放下條待執(zhí)行的指令在該段的偏移地址,把它們合在一起可在該內(nèi)存段內(nèi)取到下次要執(zhí)行的指令。
DS(Data Segment)和 ES(Extra Segment)
段寄存器DS指向數(shù)據(jù)段,ES指向附加段,在存取操作數(shù)時,二者之一和一個偏移量合并就可得到存儲單元的物理地址。該偏移量可以是具體數(shù)值、符號地址和指針寄存器的值等之一,具體情況將由指令的尋址方式來決定。
SS(Stack Segment)
段寄存器SS指向用于堆棧的內(nèi)存段,SP是用來指向該堆棧的棧頂,把它們合在一起可訪問棧頂單元。另外,當(dāng)偏移量用到了指針寄存器BP,則其缺省的段寄存器也是SS,并且用BP可訪問整個堆棧,不僅僅是只訪問棧頂。
指針指令寄存器IP
這個寄存器的功能是指向下一條要執(zhí)行的指令
準(zhǔn)確來說應(yīng)該是IP寄存器存放下條待執(zhí)行的指令在代碼段中的段內(nèi)偏移地址
這里需要明確的是IP寄存器并不是存放當(dāng)前正在執(zhí)行的指令
而在代碼段中的段內(nèi)偏移地址哦~
20位地址加法器
地址加法器的作用就是將 四個段地址其中一個的基地址 和 一個段內(nèi)偏移地址 進(jìn)行一定的運算,最終得出一個存儲單元的物理地址
那么我們怎么知道當(dāng)前是哪個基地址和段內(nèi)偏移地址呢?
這就需要看當(dāng)前CPU進(jìn)行的是什么操作了
如果CPU中的BIU是要取指令的話,那么基地址就是CS段寄存器中存放的基地址,段內(nèi)偏移地址就是指令指針寄存器IP中存放的偏移地址
如果CPU中BIU當(dāng)前是要讀寫數(shù)據(jù)的話,那么基地址就是DS或者ES中存放的基地址,段內(nèi)偏移地址址就是某個寄存器中存放的偏移地址呢
6個字節(jié)(一個字節(jié)是8bit)的指令緩沖隊列
8086的指令緩沖隊列有6個字節(jié), 當(dāng)指令緩沖隊列出現(xiàn)2個空字節(jié), BIU就自動執(zhí)行一次取指令周期,將下一條要執(zhí)行的指令從內(nèi)存單元讀入指令緩沖隊列。它們采用“先進(jìn)先出”原則(可以理解成一個管道,先進(jìn)去的就從下面漏下來了),按順序存放,并按順序取到EU中去執(zhí)行。
當(dāng)EU執(zhí)行一條需要到存儲器或I/O端口讀取操作數(shù)的指令時,BIU將在執(zhí)行完現(xiàn)行取指令的存儲器周期后的下一個存儲周期,對指令所指定的存儲單元或I/O端口進(jìn)行訪問,讀取的操作數(shù)經(jīng)BIU送EU進(jìn)行處理。
當(dāng)EU執(zhí)行跳轉(zhuǎn)、子程序調(diào)用或返回指令時(比如c語言中的goto關(guān)鍵字編譯成匯編語言之后就是執(zhí)行跳轉(zhuǎn)到某一條指令),BIU就使指令緩沖隊列復(fù)位,并從指令給出的新地址開始取指令,新取的第1條指令直接經(jīng)指令隊列送EU執(zhí)行,隨后取來的指令將填入指令緩沖隊列。
總線控制電路
是微處理器與外界總線連接的電路
在8086中包括三組總線:20位地址總線,16位雙向數(shù)據(jù)總線,一組控制總線
執(zhí)行部件EU的組成
執(zhí)行部件EU負(fù)責(zé)指令的執(zhí)行
它包含了算數(shù)邏輯單元(ALU)以及EU控制系統(tǒng)
ALU是16位加法器,用于對寄存器和指令操作數(shù)進(jìn)行算術(shù)或者邏輯運算。
EU控制系統(tǒng)接受從BIU的指令緩沖隊列中取出的指令代碼,然后對其進(jìn)行譯碼,和向EU內(nèi)有關(guān)部分發(fā)出時序命令信號。
它由如下幾部分組成:
4個通用寄存器AX,BX,CX,DX
這四個通用寄存器可以做為4個16位寄存器使用,也可以作為8個8為寄存器使用
當(dāng)做為8位寄存器使用的時候
每個16位寄存器可以分為兩個8位寄存器
如:16位寄存器AX可以分為AH(高8位)和AL(低8位)
當(dāng)4個通用寄存器中某個當(dāng)做16位寄存器使用的時候進(jìn)行的是字操作,一次操作兩個存儲單元的數(shù)據(jù)(1個存儲單元是8位數(shù)據(jù),也就是一字節(jié),2字節(jié)為一個字)
當(dāng)做8位寄存器使用的時候進(jìn)行的是字節(jié)操作
AX也成為累加器,cpu的許多指令都是利用累加器來執(zhí)行的,一般都在運算指令執(zhí)行前,累加器中存放一操作數(shù),指令執(zhí)行后,由累加器保存運算結(jié)果。
4個專用寄存器SP、BP、SI、DI
SP(Stack Pointer)為堆棧指針寄存器,當(dāng)進(jìn)行棧操作的時候,SP中存放的始終是棧頂?shù)刂?/p>
BP(Base Pointer)為基址指針寄存器,它的用途有點特殊,是和堆棧指針SP聯(lián)合使用的,作為SP校準(zhǔn)使用的,只有在尋找堆棧里的數(shù)據(jù)和使用個別的尋址方式時候才能用到。
example:
比如說,堆棧中壓入了很多數(shù)據(jù)或者地址,你肯定想通過SP來訪問這些數(shù)據(jù)或者地址,但SP是要指向棧頂?shù)?,是不能隨便亂改的,這時候你就需要使用BP,把SP的值傳遞給BP,通過BP來尋找堆棧里數(shù)據(jù)或者地址.一般除了保存數(shù)據(jù)外,可以作為指針寄存器用于存儲器尋址,此時它默認(rèn)搭配的段寄存器是SS-堆棧段寄存器.BP是16位的,再擴(kuò)充16位就是EBP,用于32位編程環(huán)境的.一般高級語言的參數(shù)傳遞等等,轉(zhuǎn)換為匯編后經(jīng)常由BP/EBP來負(fù)責(zé)尋址\處理.
SP,BP一般與段寄存器SS 聯(lián)用,以確定堆棧寄存器中某一單元的地址,SP用以指示棧頂?shù)钠频刂?,而BP可 作為堆棧區(qū)中的一個基地址,用以確定在堆棧中的操作數(shù)地址。
在一般編寫程序的時候我們習(xí)慣使用SP指向棧頂,BP指向棧底。
SI(Source Index 源變址寄存器)和 DI( Destination Index 目標(biāo)變址寄存器)
SI、DI寄存器一般與數(shù)據(jù)段寄存器DS配合使用,由于SI寄存器有自動增量功能,DI寄存器有自動減量功能,所以用于變址還是很方便的。
在串處理指令(是一種匯編指令)中SI 和DI作為隱含的源變址和目的變址寄存器,此時 SI和DS聯(lián)用,DI和ES聯(lián)用,分別達(dá)到在數(shù)據(jù)段和附加段中尋址的目的。
標(biāo)志寄存器Flag(16位)
該寄存器中7位是未用的,0-7位與Intel的8位微型機(jī)相同
其余的9位每一位都是一個標(biāo)志
分為如下兩部分
- 狀態(tài)標(biāo)志:SF、ZF、PF、CF、AF、OF
狀態(tài)標(biāo)志表示了前面的操作執(zhí)行后,ALU處于何種狀態(tài),可能會影響到后面的操作- 控制標(biāo)志:DF、IF、TF
人為設(shè)置的、可以用專門的設(shè)置、刪除指令。對某種功能起限制作用
狀態(tài)標(biāo)志:
- SF(符號標(biāo)志Sign Flag)和運算結(jié)果的最高位相同, 指出了當(dāng)前運算后的結(jié)果是正是負(fù)。
- ZF(零標(biāo)志Zero Flag) 若當(dāng)前運算結(jié)果為0,ZF為1,否則ZF為0。
- PF (奇數(shù)/偶數(shù)標(biāo)志 Parity Flag)如果運算結(jié)果中的低八位中所含的1的個數(shù)為偶數(shù)、PF為1,否則為0。
- CF(進(jìn)位標(biāo)志Carry Flag)如果加法操作使最高位產(chǎn)生進(jìn)位,或減法操作使最高位有借位的時候,CF為1,循環(huán)操作也會影響這一標(biāo)志。
- AF(輔助進(jìn)位標(biāo)志Auxiliary Carry Flag)加法運算時,如果第三位向第四位進(jìn)位,或在減法運算時,第四位向第三位借位時,AF為1,否則為0。(常用于BCD碼調(diào)整)
- OF(溢出標(biāo)志Overflow Flag)在運算過程中如果操作結(jié)果超過了模值能表示的數(shù)值范圍的時候稱之為溢出,OF為1,否則為0。
控制標(biāo)志:
- DF(方向標(biāo)志Direction Flag)操作串操作命令方向的標(biāo)志。
如果DF為0,串操作過程中地址自增,如果為1,串操作過程中地址自減。(上文說SI、DI兩個寄存器擁有自增自減的功能,就是用這個標(biāo)志位去影響的)- IF(中斷標(biāo)志Interrupt Flag)控制可屏蔽中斷的標(biāo)志。
如果IF為0,CPU不能對可屏蔽中斷進(jìn)行響應(yīng),為1時則可對可屏蔽中斷做出響應(yīng)。- TF(跟蹤標(biāo)志Trap Flag)
當(dāng)追蹤標(biāo)志TF被置為1時,CPU進(jìn)入單步執(zhí)行方式,即每執(zhí)行一條指令,產(chǎn)生一個單步中斷請求。這種方式主要用于程序的調(diào)試。
時鐘周期
CPU的晶振的工作頻率的倒數(shù)。是計算機(jī)中最基本的時間單位。
機(jī)器周期
完成一個基本操作的時間單元,如取指周期,取數(shù)周期。
指令周期
執(zhí)行一條指令所需的全部時間。一般以機(jī)器周期為單位,分單指令執(zhí)行周期、雙指令執(zhí)行周期等?,F(xiàn)在的處理器的大部分指令 (ARM、DSP)均采用單指令執(zhí)行周期。
總線周期
CPU對存儲或外設(shè)讀寫一次所需的時間,最基本的總線周期包含四個時鐘周期。
在一個最基本的總線周期中,習(xí)慣上將四個時鐘周期稱為四個狀態(tài),分別是T1,T2,T3,T4
在T1狀態(tài)時,CPU往地址/數(shù)據(jù)總線上發(fā)出地址信號, 指出要尋找的存儲單元或外設(shè)端口的地址
在T2狀態(tài)時,CPU從總線上撤銷地址,從而使16位地址/數(shù)據(jù)總線 浮置為高阻狀態(tài),為數(shù)據(jù)傳輸做準(zhǔn)備。
在T3狀態(tài)時, 16位地址/數(shù)據(jù)總線上出現(xiàn)CPU要讀寫的數(shù)據(jù),如果存儲器或者I/O接口速度慢,CPU會插入一個或者多個附加的TW狀態(tài),也稱為等待狀態(tài)
在T4狀態(tài)時,完成對數(shù)據(jù)的讀寫操作,總線周期結(jié)束。
ps:如果在當(dāng)前CPU不從存儲器或者I/O接口讀寫數(shù)據(jù),那么總線處于TI狀態(tài),也稱為空閑狀態(tài)。
最大模式和最小模式
8086/8088可以在兩種模式下工作:最大模式和最小模式,取決于硬件。
最小模式下整個微型計算機(jī)系統(tǒng)只有一個CPU,所有的總線控制信號都由這個CPU直接產(chǎn)生,因此,總線的控制電路被減到最小。
最大模式下整個微型計算機(jī)系統(tǒng)包括兩個或兩個以上的CPU,其中一個作為主處理器,其他的稱為協(xié)處理器,協(xié)助主處理器進(jìn)行工作。