#### 第9章:
#### 匯編語言
機器語言是機器指令的集合。機器指令是一列二進制數字。計算機將之轉變為一列高低電平,以使計算機的電子器件受到驅動,進行運算。執行指令由`CPU`來完成,也就是我們常說的微處理器,芯片。
每一種CPU由于硬件設計內部結構不同,需要不同的電平脈沖來控制,所有有一套屬于自己的機器指令。
用8086CPU完成s=768+1288-1280的機器碼如下:
1011100000000000000000000
0000010100000000000110000
0010110100000000000000101
如果寫錯了是否很難找到。由于比難于辨認和記憶,產生了匯編語言。
匯編語言是機器指令便于記憶的書寫格式,例如操作將寄存器BX傳送到AX中:
機器指令:1000100111011000
匯編指令:mov ax,bx
匯編語言由匯編指令、偽指令、其他符號組成。
#### 9.1 基礎知識
##### 存儲器
CPU是計算機的核心部件,它掌控整個計算機的運行并進行運算。想要讓一個CPU工作,就必須向他提供指令和數據。指令和數據在存儲器中存放,也就是我們平時所說的內存。沒有內存,CPU沒法工作,再聰明的大腦沒有記憶也無法工作。磁盤不同于內存,磁盤的作用是做數據持久化。CPU需要使用磁盤的數據內容時需要磁盤先將數據放到內存中,CPU使用內存的數據。
##### 指令和數據
在內存和磁盤上,指令和數據沒有任何區別,都是二進制信息。CPU在工作的時需要將信息作為指令或數據。為同樣的信息賦予了不同意義。
例如:
1000100111011000 >>89D8H(作為數據)
1000100111011000 >>mov ax,bx(作為程序)
##### 存儲單元
存儲器被劃分為若干個存儲單元,每個存儲單元從0開始順序編號,例如一個存儲器有128個存儲單元,編號從0-127。
:-: 
計算機最小信息單位是bit(比特),也就是一個二進制位。8個bit組成一個Byte(B,字節)。
所以微型計算器的存儲單元可以存儲一個Byte,也就是8個二進制位(8位,8bit)。
所以擁有128個存儲單元的存儲器,我們可以說它的容量是128個字節。
1KB=1024B 1MB=1024KB 1GB=1024MB 1TB=1024GB (2的10次方)
#### 9.2 CPU
CPU通過`三大總線`:`地址總線`、`控制總線`、`數據總線`與外部器件(內存、現存、接口卡等)進行數據的讀寫。
:-: 
CPU讀取內存過程
(1)CPU通過地址線將信息3發出。
(2)CPU通過控制線發出內存讀命令,選中存儲器芯片,通知它將會從中讀取信息。
(3)存儲器將3號單元中的數據8通過數據線傳入CPU。
寫操作類似。
##### 地址總線

地址總線上發送的地址信息
計算中一根導線可以傳送的穩定狀態只有兩種,高電平或低電平。用二進制表示為0或1。10根導線可以傳送10位二進制數據。10位二進制可以表示多少個不同的數據呢。2的10次方。最小數為0,最大數為1023。
所以地址總線如果有10根地址線,直接可以尋找1024個存儲單元(實際中會有段地址加偏移地址找到1024以外的存儲單元,之后章節會講)。
一個CPU有N根地址線,則可以說這個CPU的地址總線寬度為N。這樣的CPU最多可以尋找2的N次方個內存單元。
##### 數據總線
CPU與內存或其他器件之間的數據傳送是通過數據總線來進行的。數據總線的寬度決定了CPU和外界的數據傳送速度。8根數據總線一次可以傳送8位二進制數據(1個字節)。16根數據總線一次可傳送兩個字節。
8088CPU的數據總線寬度位8,8086CPU的數據總線寬度為16。
:-: 
8位數據總線傳送的信息
:-: 
16位數據總線傳送的信息
8086CPU有16根數據線,一次可以傳16位數據。8088CPU只有8根數據線,一次只能傳8位數據,寫入89D8H時需要進行兩次數據傳送。
##### 控制總線
CPU對外部器件的控制是通過控制總線來進行的。控制總線是一些不同控制線的集合。有多少根控制總線就意味著CPU提供了對外部器件的多少種控制。所以控制總線的寬度決定了CPU對外部器件的多少種控制能力。
內存讀命令或寫命令是有幾根控制總線綜合發出的。
##### 內存地址控制(概述)
一個CPU的地址總線寬度位10。那么可以尋址1024個內存單元,這1024個內存單元就構成了這個CPU的內存地址空間。
##### 主板
每臺計算機都有一個主板,主板上有核心器件和一些主要器件,這些器件通過總線相連。這些器件有CPU、存儲器、外圍芯片組、擴展插槽等。擴展插槽一般插有RAM內存條和各類接口卡。
##### 接口卡
在計算機系統中,所有可用程序控制其工作的設備,必須受到CPU的控制。CPU對外部設備不能直接控制,如顯示器、音響、打印機等。直接控制這些設備進行工作的是插在擴展插槽上的接口卡。擴展插槽通過總線與CPU相連,所以接口卡與CPU也通過總線相連。
##### 各類存儲器芯片
一臺計算機中有多個存儲器芯片。從讀寫屬性上分為兩類:隨機存儲器(RAM),只讀存儲器(ROM)。
隨機存儲器可讀可寫,必須帶電存儲,關機后的內容丟失;只讀存儲器只能讀取不能寫入。
`隨機存儲器`
用于存放供CPU使用的絕大部分程序和數據,主隨機存儲器一般由兩個位置上的RAM組成。裝在主板上的RAM和在插在擴展槽的RAM。
`裝有BIOS(基本輸入/輸出系統)的ROM`
BIOS是由主板和各類接口卡廠商提供的軟件系統,可以通過它利用該硬件設備進行最基本的輸入輸出。
`接口卡上的RAM`
某些接口卡需要對大批量輸入、輸出數據進行暫時存儲,在其上裝有RAM。最典型的是顯示卡的RAM。
:-: 
##### 內存地址空間
存儲器物理上是獨立的器件,但有兩個特點:
1. 都和CPU的總線相連。
2. CPU對它們進行讀或寫的時候通過控制總線發出內存讀寫命令。
所以CPU在操作它們的時候,把它們都當作內存來對待,把它們總的看作一個由若干存儲單元組成的`邏輯存儲器`。這個邏輯存儲器就是我們所說的`內存地址空間`。 而`虛擬內存空間`是由操作系統將其抽象出來的。
:-: 
內存地址空間的大小受CPU地址總線寬度的限制。8086CPU的總線寬度為20.可以傳送2的20次個不同的之地信息(0到2的20次方-1)。即可以定位2的20次方個內存單元,則8086CPU的內存地址空間為1MB。80386CPU的地址總線寬度為32,則地址空間為4GB。
#### 9.3 寄存器
一個CPU由運算器、控制器、寄存器等器件構成,這些器件靠內部總線相連。
在CPU中:
1. 運算器進行信息處理。
2. 寄存器進行信息存儲。
3. 控制器控制各種器件進行工作。
4. 內部總線連接各種器件,使它們之間可以進行數據的傳送。
CPU中主要的部件是寄存器。寄存器是CPU中程序員可以用指令讀寫的部件。程序員通過改變寄存器中的內容來實現對CPU的控制。
不同的CPU,寄存器的個數、結構是不同的。8086CPU由14個寄存器,每個寄存器都有一個名稱:AX、BX、CX、DX、SI、DI、SP、BP、IP、CS、SS、DS、ES、PSW。
##### 通用寄存器
:-: 
現在的8086CPU的寄存器可以存儲一個16位的數據,因為上一代的寄存器是8位的,需要兼容。
所以
AX可以分為AH和AL;
BX可以分為BH和BL;
CX可以分為CH和CL;
DX可以分為DH和DL;
AH、BH、CH、DH是高位字節(8位)
AL、BL、CL、DL是低位字節(8位)
##### 幾條匯編指令
mov ax,18 將18送入寄存器AX
mov ah,78 將78送入寄存器AH
add ax,8 將寄存器AX中的數字加8
mov ax,bx 將寄存器BX中的數據送入寄存器AX
add ax,bx 將寄存器AX中的數據加上寄存器BX中的數據存入寄存器AX中
注意內存溢出問題
例如:AH為8位,十進制最大值是256,二進制是11111111(256-1)。如果將256送入AH。則AH會變成00000000。進的數字會被拋棄,導致數據錯誤。
##### 物理地址
CPU要訪問內存單元時,要給出內存單元的地址。所有內存單元構成的存儲空間是一個一維的線性空間,每一個存儲單元在這個空間中都有一個唯一的地址,我們將這個唯一的地址稱為物理地址。
##### 16位結構的CPU
16位的CPU有以下幾個特點
1. 運算器一次最多可以處理16位的數據。
2. 寄存器最大寬度為16。
3. 寄存器和運算器之間的通路為16位。
##### 8086CPU給出物理地址的方法
1. CPU中相關的部件提供兩個16位地址,一個稱為`段地址`,另一個稱為`偏移地址。`
2. 段地址和偏移地址通過內部總線送入一個稱為`地址加法器`的部件。
3. 地址加法器將兩個16位地址合成一個20位的物理地址。
4. 地址加法器通過內部總線將20位物理地址送入輸入輸出控制電路。
5. 20位物理地址被地址總線傳送到存儲器。
地址加法器采用`物理地址=段地址X16+偏移地址`的方法用段地址和偏移地址合成物理地址。
16位的段地址X16得到20位地址。偏移地址負責具體向前或者向后的地址偏移量。
##### 不同寄存器的作用
CPU中的寄存器作用是不一樣的。
一些保留段地址偏移地址幫助尋找物理地址CS、DS、SS、ES。
一些存儲數據AX、BX、CX、DX。
一些存儲指令CS:IP。
##### 字的概念
字是兩個字節,16位。一個字節是8位。所以很多CPU傳送一次的數據是一個字。
##### 棧機制
CPU和大部分程序都會有棧機制。棧是一種數據結構,遵從先進后出。
比如:一個盒子可以放三條褲子,放的順序是第一條第二條第三條,而拿出來的順序是第三條第二條第一條。
在計算機硬件設計和軟件設計,確定運行順序是很有必要的。所以棧是常見的一種運行機制(和數據結構)。
注意:避免`棧段`超界。