# **段前缀的使用**
指令"mov ax,\[bx\]"中,内存单元的偏移地址由bx给出,而段地址默认在ds中。我们可以在访问内存单元的指令中显式地给出内存单元的段地址所在的段寄存器。比如:
1) mov ax,ds:[bx]将一个内存单元的内容送入ax,这个内存单元的长度为2字节(字单元),存放一个字,偏移地址在bx中,段地址在ds中。
2) mov ax,cs:[bx]将一个内存单元的内容送入ax,这个内存单元的长度为2字节(字单元),存放一个字,偏移地址在bx中,段地址在cs中。
3) mov ax,ss:[bx]将一个内存单元的内容送入ax,这个内存单元的长度为2字节(字单元),存放一个字,偏移地址在bx中,段地址在ss中。
4) mov ax,es:[bx]将一个内存单元的内容送入ax,这个内存单元的长度为2字节(字单元),存放一个字,偏移地址在bx中,段地址在es中。
5) mov ax,ss:[0]将一个内存单元的内容送入ax,这个内存单元的长度为2字节(字单元),存放一个字,偏移地址为0,段地址在ss中。
6) mov ax.cs:[0]将一个内存单元的内容送入ax,这个内存单元的长度为2字节(字单元),存放一个字,偏移地址为0,段地址在cs中。这些出现在访间内存单元的指令中,用于显式地指明内存单元的段地址的"ds:" "cs:" "ss:" "es:" ,在汇编语言中称为段前缀。
**汇编异常:在编译连接后,mov al,[0000]变成了mov al,00、mov bl,[0001]变成了mov bl,01、mov cl,[0002]变成了mov cl,02、mov dl,[0003]变成了mov dl,03**
解决办法:在[idata]前显示的加上段寄存器(即段前缀的用法)
![](https://img.kancloud.cn/da/2d/da2d7ab0b106ba8d8ead2dd7f791870c_1852x1020.png)
**计算ffff:0~ffff:b字节单元中的数据的和, 结果存入dx中**
分析:
* (1)运算后的结果是否会超出dx所能存储的范围?
fff:0 ~ fff:b-内存单元中的数据是字节型数据,范围在0~255之间, 12个这样的数据相加,结果不会大于65535(最大3060),所以可以在dx中存放下。
* (2)是否可以将fff:0 ~fffb中的数据直接累加到dx中?
add ds:[addr] ;(dx)=(dx)+?
期望:取出内存中的8位数据进行相加
实际:取出的是内存中的16位数据
* (3)是否可以将fff:0~fft:b中的数据直接累加到dl中?
add dl:[addr] ;(dl)=(dl)+?
期望:取出内存中的8位数据相加
实际:取出的是内存中的8位数据,但很有可能造成进位丢失(相加超出8位会被丢弃)。
对策:取出8位数据,加到16位的寄存器
mov al, ds:[addr]
mov ah, 0
add dx, ax
![](https://img.kancloud.cn/2a/5b/2a5b7c0e5d71ad9a4733ef56ddacca67_1882x1010.png)
**将内存ffff:0~ffff:b字节单元中的数据拷贝到0:200~0:20b单元中**
分析:0:200-0:20b单元等同于0020:0-0020:b单元,它们描述的是同一段内存空间
>实际地址=段地址\*16+偏移地址
1.段地址:0000,偏移地址:0200 则,实际地址=0000H\*16+0200H\=00000H+0200H=00200H
2.段地址:0020,偏移地址:0000 则,实际地址=0020H\*16+0000H=00200H+0000H=00200H
![](https://img.kancloud.cn/7e/78/7e78fd51cad87edf31b57a0b2c562f2d_1887x1030.png)
```
assume cs:code
code segment
mov bx,0
mov cx,12
s:mov ax,0ffffH
mov ds,ax #(ds)=ffffH
mov dl,[bx] #(ffff:0)=(dl)=EA即通用寄存器(dx)=00EAH、(ffff:1)=00C0H、...
mov ax,0020H #段地址是0020H则(物理地址=段地址x16+偏移地址)得出20H就是物理地址的200
mov ds,ax #(ds)=0020
mov[bx],dl #(0020:0)=00EAH、(0020:1)=00C0H、...
inc bx
loop s
mov ax,4c00H
int 21H
code ends
end
```
改进
```
assume cs:code
code segment
mov ax,0ffffH
mov ds,ax # (ds)=ffffH
mov ax,0020H
mov es,ax # 附加段寄存器(es)=0020H
mov bx,0
mov cx,12
s:mov dl,[bx] #(ffff:0)=(dl)=EAH即(dx)=00EAH
mov es:[bx],dl #(0020:0)=00EAH
inc bx #bx累加
loop s
mov ax,4c00H
int 21H
code ends
end
```
# **在代码段中使用数据**
>[danger]上面这个程序是危险的,因为在程序中直接写入地址危险比如`mov ax,0ffffH
、mov ax,0020H`,那么安全的存放这个数据应该存放在哪呢?
对策:
>[info]在程序的段中存放数据,运行时由操作系统分配空间。
段的类别:数据段、代码段、栈段
各种段中均可以有数据
可以在单个的段中安置,也可以将数据、代码、栈放入不同的段中。
![](https://img.kancloud.cn/2f/0f/2f0f87165ec50788e5d69bd86a9223d4_827x437.png)
![](https://img.kancloud.cn/9a/cc/9acce65164aab367452fd22851f6c5ba_1829x1012.png)
改进
![](https://img.kancloud.cn/e9/be/e9bedee8bcdc5a928ee262fb99c86874_1835x890.png)
![](https://img.kancloud.cn/3b/ed/3bedd7db846261d4d492067e460c427e_1809x955.png)