[TOC]
CPU是計算機的核心部件,它控制整個計算機的運作并進行運算。要想讓一個CPU工作,就必須向它提供指令和數據。指令和數據在存儲器中存放,也就是我們平時所說的內存。在一臺PC機中內存的作用僅次于CPU,離開了內存,性能再好的CPU也無法工作。這就像再聰明的大腦,沒有了記憶也無法進行思考。磁盤不同于內存,磁盤上的數據或程序如果不讀到內存中,就無法被CPU使用。
要靈活地利用匯編語言編程,我們首先要了解CPU是如何從內存中讀取信息,以及向內存中寫入信息的。
## **指令和數據**
指令和數據是應用上的概念。在內存或磁盤上,指令和數據沒有任何區別,都是二進制信息。CPU在工作的時候把有的信息看作指令,有的信息看作數據,為同樣的信息賦予了不同的意義。就像圍棋的棋子,在棋盒里的時候沒有任何區別,在對弈的時候就有了不同的意義。
例如,內存中的二進制信息100010011101000,
計算機可以把它看作大小為89D8H的數據來處理,
也可以將其看作指令mov ax,bx來執行。
```
1000100111011000 -> 89D8H (數據)
1000100111011000 -> mov ax,bx (程序)
```
計算機內存中,最小的存儲單位是“位(bit)”,8個“位”構成一個“字節(byte)”,字節是內存的屬基本單位,也是編址單位,例如,某計算機的內存是2GB,指的就是該計算機的內存中共有2×1024×1024×1024個字節。計算機的性能越強,一次運算所能處理的“位”越多,例如16位計算機一次運算能處理16個“位”,即兩個“字節”,稱為一個“字”。所以,一個“字”有幾個“字節”構成和計算機的型號有關。例如32位計算機中,一個“字”就是四個“字節”。
**字通常分為若干個字節(每個字節一般是8位)。**
例如一臺8位機(多少位是由數據總線決定的),它的1個字就等于1個字節,字長為8位。
如果是一臺16位機,那么,它的1個字就由2個字節構成,字長為16位。
**在存儲器中,通常每個單元存儲一個字還是字節?**
地址總線的寬度的寬度決定了每個存儲單元的大小是多少位(比如說1條地址線只能訪問2個不同的單元,2條地址線則能訪問4個不同的單元)
## **存儲單元**
存儲器被劃分為若干存儲單元,地址總線的寬度(根數)決定了多少個存儲單元(每個地址對應一個存儲單元)
假如某個存儲器(內存)有128個存儲單元:那么這些存儲單元的編號(0~127)可愛伊看做是存儲單元在存儲器中的地址,cpu要從存儲器(內存)中讀取數據首先要指定存儲單元的地址(注意cpu可操作的不止內存這一種器件)

```
20地址總線:存儲單元0~FFFFF(2^20-1=1048575 ),尋址能力2^20=1048576=1M
為什么是2^20? 地址有是從全是0~全是1這么多個
000...00
010...00
001...00
...
111...11
```
那么一個存儲單元能存儲多少信息呢?
我們知道電子計算機的最小信息單位是bit(比特),也就是一個二進制位。8個bit組成一個Byte,也就是通常講的一個字節。微型機存儲器的存儲單元可以存儲一個Byte, 即8個二進制位。假如一個存儲器有128個存儲單元,它可以存儲128個Byte.微機存儲器的容量是以字節為最小單位來計算的。對于擁有128個存儲單元的存儲器,我們可以說,它的容量是128個字節。
## **總線(BUS)**
那么CPU是通過什么將地址、數據和控制信息傳到存儲器芯片中的呢?電子計算機能處理、傳輸的信息都是電信號,電信號當然要用導線傳送。在計算機中專門有**連接CPU和其他芯片的導線,通常稱為總線(BUS)**。總線從物理上來講,就是一根根導線的集合(在物理上表現為一根根的密密麻麻的針腳【引腳】)。
根據傳送信息的不同,總線從邏輯上又分為3類,**地址總線**、**控制總線**和**數據總線**。

### **地址總線**
CPU是通過地址總線來指定存儲器單元的。可見地址總線上能傳送多少個不同的信息, CPU就可以對多少個存儲單元進行尋址。
一根地址總線可以表示兩種狀態(高電平、低電平二進制表示0、1)
20根地址總線(可表示1048576種狀態)=2*20次方=1024Byte*1024Byte=1048576=1MB
一個CPU有N根地址線,則可以說這個CPU的地址總線的寬度為N。這樣的CPU,最多可以尋找2的N次方個內存單元。
下圖是具有10根地址線的CPU向內存發出地址信息11時10根地址線上·傳送的二進制信息(10根地址總線即地址總線寬度為10):

8086pc機 內存地址空間分配方案(每個指令集分配方案都不一樣,所以每個指令集首先要找到它的分配方案)
### **數據總線**
CPU與內存或其他器件之間的數據傳送是通過數據總線來進行的。
數據總線的寬度決定了CPU和外界的數據傳送速度。
* 8根數據總線一次可傳送一個8位二進制數據(即一個字節)。
* 16根數據總線一次可傳送兩個字節。
8088CPU的數據總線寬度為8, 8086CPU的數據總線寬度為16,
我們來分別看一下它們向內存中寫入數據89D8H時,是如何通過數據總線傳送數據的。圖1.5展示了8088CPU數據總線上的數據傳送情況:圖1.6展示了8086CPU數據總線上的數據傳送情況。

8086有16根數據線,可一次傳送16位數據,所以可一次傳送數據89D8H;而8088只有8根數據線,一次只能傳8位數據,所以向內存寫入數據89D8H時需要進行兩次數據傳送。
數據總線的寬度決定了數據的傳輸速度是多少位

windows64位的數據總線寬度為64
### **控制總線**
CPU對外部器件的控制是通過控制總線來進行的。在這里控制總線是個總稱,控制總線是一些不同控制線的集合。有多少根控制總線,就意味著CPU提供了對外部器件的多少種控制。所以,控制總線的寬度決定了CPU對外部器件的控制能力。前面所講的內存讀或寫命令是由幾根控制線綜合發出的,其中有一根稱為“讀信號輸出”的控制線負責由CPU向外傳送讀信號, CPU向該控制線上輸出低電平表示將要讀取數據;有一根稱為“寫信號輸出”的控制線則負責傳送寫信號。
### **cpu從存儲器讀寫數據**
8086cpu有20條地址總線,那么他最大尋址為0~1048575(0~FFFFF)
而它的寄存器確實16位的,那么寄存器只能存放0~65535(0~FFFF)
解決辦法是段地址*16+偏移地址組合成0~FFFFF
cpu從3號單元讀取數據過程:
* (1) CPU通過地址線將地址信息3發出。
* (2) CPU通過控制線發出內存讀命令,選中存儲器芯片,并通知它,將要從中讀取數據。
* (3)存儲器將3號單元中的數據8通過數據線送入CPU.

cpu寫入數據同理,如向3號單元寫入數據26:
* (1) CPU通過地址線將地址信息3發出。
* (2) CPU通過控制線發出內存寫命令,選中存儲器芯片,并通知它,要向其中寫入數據。
* (3) CPU通過數據線將數據26送入內存的3號單元中。
## **小結**
(1)匯編指令是機器指令的助記符,同機器指令一對應。
(2)每一種CPU都有自己的匯編指令集。
(3) CPU可以直接使用的信息在存儲器中存放。
(4)在存儲器中指令和數據沒有任何區別,都是二進制信息。
(5)存儲單元從零開始順序編號。
(6)一個存儲單元(即1字節)可以存儲8個bit,即8位二進制數。
(7) 1Byte=8bit 1KB=1024B 1MB=1024KB 1GB=1024MB.
(8)每一個CPU芯片都有許多管腳,這些管腳和總線相連。也可以說,這些管腳引出總線。一個CPU可以引出3種總線的寬度標志了這個CPU的不同方面的性能:
* 地址總線的寬度決定了CPU的尋址能力(2^N,N為地址總線寬度)
* 數據總線的寬度決定了CPU與其他器件進行數據傳送時的一次數據傳送量;
* 控制總線的寬度決定了CPU對系統中其他器件的控制能力。
## **測驗**
(1) 1個CPU的尋址能力為8KB,那么它的地址總線的寬度為?
```
1024*8=8192字節=2^13
```
(2) 1KB的存儲器有?個存儲單元。存儲單元的編號從 ?到?
```
1024
0~1023
```
(3) 1KB的存儲器可以存儲?個bit,?個Byte
```
1024*8=8192
1024
```
(4) 1GB. 1MB. 1KB分別是?Byte.
```
1024*1024*1024
1024*1024
1024
```
(5) 8080, 8088, 80286, 80386的地址總線寬度分別為16根、20根、24根、32根,則它們的尋址能力分別為:(KB)、(MB)(MB).(GB).
```
2^16=640KB
2^20=1MB
2^24=16MB
2^32=4GB
```
(6) 8080, 8088, 8086, 80286, 80386的數據總線寬度分別為8根、8根、16根、16根、32根,則它們一次可以傳送的數據分別為:?(Byte)
```
8/8=1Byte
8/8=1Byte
16/8=2Byte
16/8=2Byte
32/8=4Byte
```
(7)從內存中讀取1024字節的數據, 8086至少要讀次, 80386至少要讀次.
```
1024/(16/8)=1024/2Byte=512
1024/(32/8)=1024/4Byte=256
```
(8)在存儲器中,數據和程序以?形式存放。
```
二進制代碼
```
## **內存地址空間**
什么是內存地址空間呢?
舉例來講,一個CPU的地址總線寬度為10,那么可以尋址1024個內存單元,這1024個可尋到的內存單元就構成這個CPU的內存地址空間。下面進行深入討論。首先需要介紹兩部分基本知識,主板和接口卡。
**主板**
在每一臺PC機中,都有一個主板,主板上有核心器件和一些主要器件,這些器件通過總線(地址總線、數據總線、控制總線)相連。這些器件有CPU,存儲器、外圍芯片組、擴展插槽等。擴展插槽上一般插有RAM內存條和各類接口卡。
**接口卡**
計算機系統中,所有可用程序控制其工作的設備,必須受到CPU的控制。CPU對外部設備都不能直接控制,如顯示器、音箱、打印機等。直接控制這些設備進行工作的是插在擴展插槽上的接口卡。擴展插槽通過總線和CPU相連,所以接口卡也通過總線同CPU相連。CPU可以直接控制這些接口卡,從而實現CPU對外設的間接控制。簡單地講,就是CPU通過總線向接口卡發送命令,接口卡根據CPU的命令控制外設進行工作。
一臺PC機中,裝有多個存儲器芯片,這些存儲器芯片從物理連接上看是獨立的、不同的器件。從讀寫屬性上看分為兩類:隨機存儲器(RAM)和只讀存儲器(ROM),隨機存儲器可讀可寫,但必須帶電存儲,關機后存儲的內容丟失;只讀存儲器只能讀取不能寫入,關機后其中的內容不丟失。這些存儲器從功能和連接上又可分為以下幾類。
* **隨機存儲器**
用于存放供CPU使用的絕大部分程序和數據,主隨機存儲器一般由兩個位置上的RAM組成,裝在主板上RAM和插在擴展插槽上的RAM.
* **裝有BIOS(Basic Input/Output System,基本輸入/輸出系統)的ROM**
BIOS是由主板和各類接口卡(如顯卡、網卡等)廠商提供的軟件系統,可以通過它利用該硬件設備進行最基本的輸入輸出。在主板和某些接口卡上插有存儲相應BIOS的ROM,例如,主板上的ROM中存儲著主板的BIOS(通常稱為系統BIOS):顯卡上的ROM中存儲著顯卡的BIOS:如果網卡上裝有ROM,那其中就可以存儲網卡的BIOS.
* **接口卡上的RAM**
某些接口卡需要對大批量輸入、輸出數據進行暫時存儲,在其上裝有RAM,最典型的是顯示卡上的RAM,一般稱為顯存。顯示卡隨時將顯存中的數據向顯示器上輸出。換句話說,我們將需要顯示的內容寫入顯存,就會出現在顯示器上。

上述的那些存儲器,在物理上是獨立的器件,但是在以下兩點上相同。都和CPU的總線相連。CPU對它們進行讀或寫的時候都通過控制線發出內存讀寫命令。
這也就是說, CPU在操控它們的時候,把它們都當作內存來對待,把它們總的看作一個由若干存儲單元組成的邏輯存儲器,這個邏輯存儲器就是我們所說的內存地址空間。在匯編這門課中,我們所面對的是內存地址空間。

在上圖中,所有的物理存儲器被看作一個由若干存儲單元組成的邏輯存儲器,每個物理存儲器在這個邏輯存儲器中占有一個地址段,即一段地址空間。CPU在這段地址空間中讀寫數據,實際上就是在相對應的物理存儲器中讀寫數據。
假設,上圖中的內存地址空間的地址段分配如下。
地址0-7FFFH的32KB空間為主隨機存儲器的地址空間;
地址8000H-9FFFH的8KB空間為顯存地址空間;
地址A000H-FFFH的24KB空間為各個ROM的地址空間。
這樣, CPU向內存地址為1000H的內存單元中寫入數據,這個數據就被寫入主隨機存儲器中; CPU向內存地址為8000H的內存單元中寫入數據,這個數據就被寫入顯存中,然后會被顯卡輸出到顯示器上: CPU向內存地址為C000H的內存單元中寫入數據的操作是沒有結果的, C000H單元中的內容不會被改變, C000H單元實際上就是ROM存儲器中的一個單元。
內存地址空間的大小受CPU地址總線寬度的限制。8086CPU的地址總線寬度為20,可以傳送20個不同的地址信息(大小從0至20-1),即可以定位220個內存單元,則8086PC的內存地址空間大小為1MB。同理, 80386CPU的地址總線寬度為32,則內存地址空間最大為4GB.
我們在基于一個計算機硬件系統編程的時候,必須知道這個系統中的內存地址空間分配情況。因為當我們想在某類存儲器中讀寫數據的時候,必須知道它的第一個單元的地址和最后一個單元的地址,才能保證讀寫操作是在預期的存儲器中進行。比如,我們希望向顯示器輸出一段信息,那么必須將這段信息寫到顯存中,顯卡才能將它輸出到顯示器上。要向顯存中寫入數據,必須知道顯存在內存地址空間中的地址。
不同的計算機系統的內存地址空間的分配情況是不同的,圖1.9展示了8086PC機內存地址空間分配的基本情況。

不同的計算機系統的內存地址空間的分配情況是不同的,上圖展示了8086PC機內·存地址空間分配的基本情況。
即8086PC機,從地址0-9FFFF的內存單元中讀取數據,實際上就是在讀取主隨機存儲器中的數據;向地址A0000-BFFFF的內存單元中寫數據,就是向顯存中寫入數據,這些數據會被顯示卡輸出到顯示器上;我們向地址C00-FFF的內存單元中寫入數據的操作是無效的,因為這等于改寫只讀存儲器中的內容。
內存地址空間
最終運行程序的是CPU,我們用匯編語言編程的時候,必須要從CPU的角度考慮問題。對CPU來講,系統中的所有存儲器中的存儲單元都處于一個統一的邏輯存儲器中,它的容量受CPU尋址能力的限制。這個邏輯存儲器即是我們所說的內存地址空間。對于初學者,這個概念比較抽象,我們在后續的課程中將通過一些編程實踐,來增加感性認識。