Description
CPU要讀寫一個內存單元的時候,必須先給出這個內存單元的地址,在8086PC中,內存地址由段地址和偏移地址組成。8086CPU中有一個DS寄存器,通常用來存放要訪問
數據的段地址。比如我們要讀取10000H單元的內容,可以用如下的程序段進行。
mov bx,1000H
mov ds,bx
mov a1,[0]
上面的3條指令將10000H(1000:0)中的數據讀到al中。
前面我們使用 mov
指令,可完成兩種傳送:
- 將數據直接送入寄存器;
- 將一個寄存器中的內容送入另一個寄存器。
也可以使用mov指令將一個內存單元中的內容送入一個寄存器中。
從哪一個內存單元送到哪一個寄存器中呢?在指令中必須指明。寄存器用寄存器名來指明,內存單元則需用內存單元的地址來指明。顯然,此時 mov
指令的格式應該是:mov
寄存器名,內存單元地址。
“[…]”表示一個內存單元,“[…]”中的0表示內存單元的偏移地址。
我們知道,只有偏移地址是不能定位一個內存單元的,那么內存單元的段地址是多少呢?
指令執行時,8086CPU自動取 ds
中的數據為內存單元的段地址。
再來看一下,如何用 mov
指令從 \(10000H\) 中讀取數據。\(10000H\) 用段地址和偏移地址表示為\(1000:0\),我們先將段地址 \(1000H\) 放入 ds
,然后用 mov al,[0]
完成傳送。mov
指令中的 []
說明操作對象是一個內存單元,[]
中的 \(0\)說明這個內存單元的偏移地址是 \(0\),它的段地址默認放在ds
中,指令執行時,8086CPU會自動從 ds
中取出。
mov bx,1000H
mov ds,bx
若要用 mov al,[0]
完成數據從 \(1000:0\) 單元到 al
的傳送,這條指令執行時,ds
中的內容應為段地址 \(1000H\) ,所以在這條指令之前應該將 \(1000H\) 送入 ds
如何把一個數據送入寄存器呢?我們以前用類似 “mov ax, l”
這樣的指令來完成,從理論上講,我們可以用相似的方式: mov ds, l000H
,來將 \(1000H\) 送入 ds
。可是,現實並非如此,8086CPU不支持將數據直接送入段寄存器的操作,ds
是一個段寄存器,所以 mov ds, l000H
這條指令是非法的。那么如何將 \(1000H\) 送入 ds
呢?只好用一個寄存器來進行中轉,即先將 \(1000H\) 送入一個一般的寄存器,如 bx
,再將 bx
中的內容送入 ds
為什么8086CPU不支持將數據直接送入段寄存器的操作?這屬於8086CPU硬件設計的問題,我們只要知道這一點就行了。
問題3.2
寫幾條指令,將 al
中的數據送入內存單元 \(0000H\) 中,思考后看分析。
分析:
怎樣將數據從寄存器送入內存單元?
從內存單元到寄存器的格式是:"mov寄存器名,內存單元地址”,
從寄存器到內存單元則是:"mov內存單元地址,寄存器名”。
\(10000H\) 可表示為 \(1000:0\) ,用 ds
存放段地址 \(1000H\) ,偏移地址是 \(0\),則 mov [0],al
可完成從 al
到 \(10000H\) 的數據傳送。完整的幾條指令是:
mov bx, 1000H
mov ds, bx
mov [0],a1
段寄存器擴展匯總
\1. 在8086CPU中,使用 \(16\) 位寄存器來存儲一個字(word). 高 \(8\) 位存放高位字節,低 \(8\) 位存放低位字節。
在內存中存儲時,由於內存單元是字節單元,則一個字(word)需要用 \(2\) 個地址連續的內存單元來存放 。
這個字(word)的低位字節存放在低地址單元中,高位字節存放在高地址單元中。
\2. 我們將起始地址為 \(N\) 的字單元簡稱為 \(N\) 地址字單元 。
如:一個字單元由 \(2、3\) 兩個內存單元組成,則這個字單元的起始地址為 \(2\) ,我們可以說這是:\(2\) 地址字單元 。
\3. 字節單元與字單元。
一個內存單元可以存儲 \(1\) 個字節數據(byte), 相當於 \(8\)位(bit)數據。稱為"字節單元"。
一個字單元,大家知道,一個字(word)等於 \(2\) 個字節(byte), 所以
一個字單元,需要 \(2\) 個地址連續的字節單元存放。
字的低字節位放在低地址字節單元中,字的高字節位放在高地址字節單元中。
\4. CPU要讀寫一個內存單元的時候,必須先給出這個內存單元的地址,在8086CPU中,內存地址由段地址和偏移地址組成。
8086CPU中有一個DS寄存器,通常用來存放要訪問數據的段地址。
如:我們要讀取 \(10000H\) 單元的內容。
則:
mov bx, 1000H
mov ds, bx
mov al, [0]
mov 指令也可以將一個內存單元中的內容送入一個寄存器中。[...]表示一個內存單元。[...]中的0表示內存單元的偏移地址。
指令執行時,8086CPU自動取DS寄存器中的數據為內存單元的段地址。
\5. 8086CPU不支持將數據直接送入段寄存器的操作 ,DS是一個段寄存器,所以 mov ds, 1000H是非法的指令 。
可以用一個寄存器來中轉,如:
mov bx, 1000H
mov ds, bx
\6. 字的傳送
因為8086CPU是 \(16\) 位結構,有 \(16\) 根數據線,所以一次性可以傳送 \(16\) 位的數據,也就是說,一次性可以傳送一個字(word).
只要mov指令中給出 \(16\) 位寄存器就可以進行 \(16\) 位數據的傳送了。如:
mov bx, 1000H
mov ds, bx
mov ax, [0] ; 1000:0 處的字形數據送入AX寄存器中
mov [0], cx ; cx寄存器中的16位數據送到1000:0處
\6. 例子
內存情況, 如下所示,寫出下面指令執行后寄存器 \(AX、BX、CX\) 中的值。
10000H 23H
10001H 11H
10002H 22H
10003h 66H
mov ax, 1000H
mov ds, ax
mov ax, [0]
mov bx, [2]
mov cx, [1]
add bx, [1]
add cx, [2]
解析:
mov ax, 1000H
mov ds, ax
上面2條指令,將DS寄存器設置為 \(1000H\) (代碼段地址)
mov ax, [0]
由於AX是16位寄存器,所以需要把字型數據送入AX
\(1000:0\) 內存單元中存儲着字型數據的低 \(8\) 位,\(23H\)
\(1000:1\) 內存單元中存儲着字形數據的高 \(8\) 位,\(11H\)
指令執行時,字型數據的高 \(8\) 位送入AH,字形數據的低 \(8\) 位送入AL,則AX寄存器的值為 \(1123H\)。
后面的原理相同。