loop和[bx]连用
计算 FFFF:0 ~ FFFF:B 单元中数据的和
1)运算结果不会超出dx的存储范围:dx 存65535,即12 * 255 < 65535
2)不能将 FFFF:0 ~ FFFF:B 的数据直接累加到 dx:FFFF:0 ~ FFFF:B 中是内存单元是8位,不能累加到16位中。
3)不能用累加 dl 和 dh=0 实现: dl有可能会产生进位
4)可以先储存到一个16位寄存器中,然后再加。
assume cs:coud
coud segment
mov ax, 0FFFFH //不能字母开头
mov ds, ax
mov dx, 0
mov bx, 0
mov cx, 12
s: mov al, ds:[bx]
mov ah, 0
add dx, ax
inc dx
loop
mov ax, 4c00H
int 21H
coud ends
end
段前缀
1)mov ax, ds:[bx] ds:0 //数据段寄存器
2)mov ax, cs:[bx] cs:ip //代码段寄存器(注意不能用mov改变cs和ip中的值)
3)mov ax, ss:[bx] ss:sp //栈寄存器
用于显示地指明内存单元地段地址的“ds:”、“ss:”、“cs:”,在汇编语言中称为段前缀。
一段安全的空间
1)我们需要直接向一段内存中写入内容。
2)这段内存空间不应存放系统或其他程序的数据或代码,否则写入操作系统很有可能引发错误。
3)DOS方式下,一般情况,0:200 ~ 0:2ff空间中没有系统或其他程序的数据或代码。
段前缀的使用
将内存FFFF:0 ~ FFFF:B单元中的数据复制到0:200 ~ 0:20b单元中。
1)0:200 ~ 0:20b单元等同于0020:0 ~ 0020:b单元,它们描述的是同一段内存空间。
2)复制使用循环实现
3)源始单元和目标单元的偏移地址是相同的,用bx来存放
4)用0020:0 ~ 0020:b描述,就是为了使目标单元的偏移地址和源始地址的偏移地址从同一数值0开始。
实现1(一个段寄存器):
assume cs:code
code segment
mov bx, 0
mov cx, 12
s: mov ax, 0FFFFH
mov ds, ax
mov dl, [bx]
mov ax, 0020H
mov ds, ax
mov [bx], dl
inc bx
loop s
mov ax, 4c00H
int 21H
code ends
end
因源始地址单元ffff和目标单元0020相距大于64KB段里,以上程序每次循环要设置两次ds。(从0FFFFH寻址不到0020H)效率不高。可以使用2个段寄存器分别存放源始单元和目标单元的段地址。
实现2(2个段寄存器):
assume cs:code
code segment
mov ax, 0FFFFH
mov ds, ax
mov ax, 0020H
mov es, ax
mov bx, 0
mov cx, 12
s: mov dl, ds:[bx]
mov es:[bx], dl
inc bx
loop s
mov ax, 4c00H
int 21H
code ends
end