匯編 | 數據段寄存器DS和[address]


Description

CPU要讀寫一個內存單元的時候,必須先給出這個內存單元的地址,在8086PC中,內存地址由段地址和偏移地址組成。8086CPU中有一個DS寄存器,通常用來存放要訪問
數據的段地址。比如我們要讀取10000H單元的內容,可以用如下的程序段進行。


mov bx,1000H
mov ds,bx
mov a1,[0]

上面的3條指令將10000H(1000:0)中的數據讀到al中。

前面我們使用 mov 指令,可完成兩種傳送:

  1. 將數據直接送入寄存器;
  2. 將一個寄存器中的內容送入另一個寄存器。

也可以使用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\)

后面的原理相同。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM