## **CPU與內存的數據交換**
要解決的問題: CPU從內存單元中要讀取數據
要求 CPU要讀取一個內存單元的時候,必須先給出這個內存單元的地址;
原理:在8086PC中,內存地址由段地址和偏移地址組成(段地址:偏移地址)
解決方案:DS和[address]配合
用DS寄存器存放要訪問的數據的段地址。指令執行時, 8086CPU自動取ds中的數據為內存單元的段地址。
偏移地址用[...]形式直接給出(這種形式段地址一定是保存在DS中的)

例子1:內存里的數據傳入寄存器
```
//將內存10000H(1000:0)中的數據讀取到cpu寄存器al中
mov bx,1000H
mov ds,bx
//mov ds 1000H 注意這種方法是錯的
mov al, [0]
```
例子2:寄存器的數據傳入內存
```
//將cpu寄存器al中的數據寫到內存10000H(1000:0)中。在8086PC中,cpu不支持將數據直接送入段寄存器
mov bx,1000H
mov ds,bx
mov [0],al
```
>[danger]套路:數據-》一般寄存器(通用寄存器)-》段寄存器
字的傳送:
```
//將1000H段地址數據傳給DS寄存器
mov bx,1000H
mov ds,bx
mov ax,[0] //將內存10000H(1000:0)處的字型數據讀取到ax中
mov [0] cx //cx中的16位數據送到內存10000H(1000:0)處
```
例子:
注意DS和[...]操作的是字數據啦!在8086一個字是16位的
```
內存 指令
--------
- - mov ax,1000H //ax=1000
10000H - 23 -
- - mov ds,ax //ds=1000
--------
- - mov ax,[0] //ax=1123 注意ds[...]操作的是字數據,8086一個字為16位
10001H - 11 -
- - mov bx,[2] //bx=6622 ds保存的是段地址,[]中指明的是偏移地址,將1000:2的字數據6622賦值到bx
--------
- - mov cx,[1] //cx=2211 將1000:1的字數據2211賦值到bx
10002H - 22 -
- - add bx,[1] //bx=8833 將1000:1的字數據2211與bx的值6622相加并賦值到bx
--------
- - add cx,[2] //cx=8833 將1000:2的字數據6622與cx的值2211相加并賦值到cx
10003H - 66 -
- -
```


## **DS與數據段(對內存單元中數據的訪問)**
對于8086PC機,可以根據需要將一組內存單元定義為一個段。
物理地址=段地址x16+偏移地址
將一組長度為N (NS64K )、地址連續、起始地址為16的倍數的內存單元當作專門存儲數據的內存空間,從而定義了一個數據段。
例:用123D0H,123B9H的空間來存放數據
* 段地址: 123BH 起始偏移地址:0000H長度:10字節
* 段地址: 1230H 起始偏移地址: 00B0H長度: 10字節
* ... ...
上面例子告訴我們 給出的方法很多
>[danger]在實際操作時,將哪段內存當作數據段? 段地址如何定,在編程時右編程人員自行安排。
處理方法:(DS):([address]),即用DS存放數據段的段地址
用相關指令訪問數據段中的具體單元,單元地址由\[address\]指出
例子:
累加數據段中的前三個單元中的數據
```
mov ax,123BH //確定段地址
mov ds,ax //將確定的段地址存入DS
mov al,0 //初始化清零
add al,[0] //開始累加
add al,[1] //
add al,[2] //
```
累加數據段中的前三個**字型**單元的數據
```
mov ax,123BH //確定段地址
mov ds,ax //將確定的段地址存入DS
mov ax,0 //初始化清零
add ax,[0] //開始累加
add axl,[2] //
add ax,[4] //
```