第五章 [BX]和 loop 指令
要完整描述一个内存单元,需要两种信息:1、内存单元的地址;2、内存单元难度长度(类型)
[ bx ] 和 [0]类似,段地址都是ds,只不过前者偏移地址变成bx,后者偏移地址是0,这里得到了内存地址,那么大小由寄存器来判断,比如mov ax,[bx]就是一个字大小;mov al,[bx]就是一个字节大小。
[bx] 的含义:[bx]表示一个内存单元,它的偏移地址在bx中,段地址默认在ds中
loop指令的格式是:loop 标号,CPU执行loop指令的时候,要进行两步操作,
-
(cx) = (cx) - 1;
-
判断 cx 中的值,不为零则转至标号处执行程序,如果为零则向下执行。
例如:计算 2 12 2^{12} 212
assume cs:code
code segment
mov ax, 2
mov cx, 11
s: add ax, ax
loop s
mov ax,4c00h
int 21h
code ends
end
5.2 loop和[bx]的联合应用
计算ffff:0 ~ ffff:
b单元中的数据的和,结果存储在dx中
问题分析:
- 这些内存单元都是字节型数据范围0 ~ 255 ,12个字节数据和不会超过65535,dx可以存下
- 对于8位数据不能直接加到dx
解决方案:
用一个16位寄存器来做中介。将内存单元中的8位数据赋值到一个16位寄存器a中,再将ax中的数据加到dx
assume cs:code
code segment
mov ax, 0ffffh
mov ds, ax
mov bx, 0
mov dx, 0
mov cx, 12
s: mov al, [bx]
mov ah, 0
add dx, ax
inc bx
loop s
mov ax, 4c00h
int 21h
code ends
end
5.3 段前缀
mov ax, ds:[bx]
mov ax, cs:[bx]
mov ax, ss:[bx]
mov ax, es:[bx]
mov ax, ss:[0]
mov ax, cs:[0]
这些出现在访问内存单元的指令中,用于显式地指明内存单元的段地址的ds: \ cs: \ ss: \ es:
,在汇编语言中称为段前缀。
注意:不能随意对某个地址的值进行覆盖,因为其可能保存其他程序的重要数据,在DOS模式下,一般0:200~0:2ff这256个字节没有被操作系统或其他程序使用,意思是以后实验可以安全(任意)使用这段地址。
注意:debug x.exe 程序加载程序后cx保存的是程序的大小,单位是字节
段前缀的使用
将内存ffff:0 ~ ffff:b
单元中的数据复制到0:200 ~ 0:20b
单元中。
assume cs:code
code segment
mov ax, 0ffffh
mov ds, ax ;(ds)= 0ffffh
mov ax, 0020h
mov es, ax ;(es)= 0020h 0:200 等效于 0020:0
mov bx, 0 ;(bx)= 0,此时ds:bx指向ffff:0,es:bx指向0020:0
mov cx,12 ;(cx)=12,循环12次
s: mov dl,[bx] ;(d1)=((ds)* 16+(bx)),将ffff:bx中的字节数据送入dl
mov es:[bx],dl ;((es)*16+(bx))=(d1),将dl中的数据送入0020:bx
inc bx ;(bx)=(bx)+1
loop s
mov ax,4c00h
int 21h
code ends
end