[bx]和loop的使用
(1)编程,向内存0:200~0:23F依次传送数据0 ~63(3FH)
assume cs:code
code segment
mov ax,20H
mov es,ax;数据传到哪里去
mov cx,64
mov bx,0
mov dl,0 ;逻辑清晰
loop setnumber:
mov es:[bx],dl
inc bx ;increase自增
inc dl
loop setnumber
mov ax,4c00h
int 21h
code ends
end
(2)编程,向内存0:200~0:23F依次传送数据0 ~63(3FH),程序中只能使用9条指令,9条指令中包括"mov ax,4c00h"和"int 21h"。
assume cs:code
code segment
mov ax,20H
mov es,ax;数据传到哪里去
mov cx,64
mov bx,0
mov dl,0 ;逻辑清晰
loop setnumber:
mov es:[bx],bl ;把dl也省了
inc bx ;increase自增
loop setnumber
mov ax,4c00h
int 21h
code ends
end
(3)下面的程序的功能是将“mov ax,4c00h”之前的指令复制到0:200处,补全程序。上机调试,跟踪运行结果。
assume cs:code
code segment:
mov ax,cs
mov ds,ax
mov ax,0020h
mov es,ax
mov bx,0
mov cx,23 ;cx决定复制多少个字节
s: mov al,ds:[bx];数据从哪里来
mov es:[bx],al
inc bx
loop s
;IP=IP+所读指令的字节数 17h-0=23=cx
mov ax,4c00h
int 21h
code ends
end
比较以下汇编源程序中以下指令的含义
mov al,[0] ——》 含义:(al)=0,将常量0送入al中,与mov al,0含义相同
mov al,ds:[0] ——》 含义:(al)=((ds)*16+0),将内存单元中的数据送入al中
mov al,[bx] ——》 含义:(al)=((ds)*16+【bx】),将内存单元中的数据送入al
mov al,ds:[bx] ——》含义:与“mov al,【bx】”相同
从上面的比较中可以看出
(1)在汇编源程序中,如果用指令访问一个内存单元,则在指令中必须用“[…]”来表示内存单元,如果在“[ ]”里用一个常量idata直接给出内存单元的偏移地址,就要在“[ ]”的前面显示地给出段地址所在的段寄存器。比如 mov al,ds:[0]
如果没有在“【】”的前面显示地给出段地址所在的段寄存器,比如
mov al,【0】
那么编译器masm把指令【idata】理解为idata。
(2)如果在“【】”中用寄存器,比如bx,间接给出内存单元的偏移地址,则段地址默认在ds中。当然也可以显式地给出段地址所在的段寄存器。
段前缀
指令“mov ax,[bx]”中,内存单元的偏移地址由bx给出,而段地址默认在ds。我们可以在访问内存单元的指令中显式地给出内存单元的段地址所在的段寄存器。比如:
(1)mov ax,ds:[bx]
将一个内存单元的内容送入ax,这个内存单元的长度为两个字节,存放一个字,偏移地址在bx中,段地址在ds中。
(2)mov ax,cs:[bx]
将一个内存单元的内容送入ax,这个内存单元的长度为两个字节,存放一个字,偏移地址在bx中,段地址在cs中。
(3)mov ax,ss:[bx]
将一个内存单元的内容送入ax,这个内存单元的长度为两个字节,存放一个字,偏移地址在bx中,段地址在ss中。
(4)mov ax,es:[bx]
将一个内存单元的内容送入ax,这个内存单元的长度为两个字节,存放一个字,偏移地址在bx中,段地址在es中。
(5)mov ax,ss:[0]
将一个内存单元的内容送入ax,这个内存单元的长度为两个字节,存放一个字,偏移地址为0,段地址在ss中。
(6)mov ax,cs:[0]
将一个内存单元的内容送入ax,这个内存单元的长度为两个字节,存放一个字,偏移地址为0,段地址在cs中。
用于显式地指明内存单元段地址的“ds:”,“cs:”,“ss:”,“es:”,在汇编语言中称为段前缀。