S1和di是8086CPU中和bx功能相近的寄存器,si和di不能够分成两个8位寄存器来使用。下面的3组指令实现了相同的功能。
(1) mov bx,0
mov ax,[bx]
(2) mov si,0
mov ax,[si]
(3) mov di,0
mov ax,[di]
下面的三组指令也实现了相同的功能:
(1) mov bx,0
mov ax,[bx+123]
(2) mov si,0
mov ax,[si+123]
(3) mov di,0
mov ax,[di+123]
问题
用S1和di实现将字符串’welcome to masm!’复制到它后面的数据区中
assume cs:codesg,ds:datasg datasg segment db 'welcome to masm!' db '............................' datasg ends
分析
我们编写的程序大都是进行数据的处理,而数据在内存中存放,所以我们在处理数据之前首先要搞清楚数据存储在什么地方,也就是说数据的内存地址.现在我们要对datasg段中的数据进行复制,我们先来看以下要复制的数据在什么地方,
datasg:0,这是要进行复制的数据的地址.那么复制到那里去呢?它后面的数据区.'welcome to masm!'从偏移地址0开始存放,长度为16个字节,所以,他们后面的数据区的偏移地址为16,就是字符串所要存放的空间,清楚了地址之后,我们就可以进行处理了.我们的ds:si指向要复制的原始字符串,用ds:di指向复制的目的空间,然后一个循环来完成复制,
代码如下:
codesg segment
start:mov ax,datasg
mov ds,ax
mov si,0
mov di,16
mov cx,8
s:mov ax,[si]
mov [di],ax
add si,2
add di,2
loop s
mov ax,4c00H
int 21H
codesg ends
end start
注意
在程序中, 我们用的16位寄存器进行内存单元之间的数据传送,一次复制2个字节,一共循环8次(si和di每次加2)
用更少的代码,实现:
分析:
我们可以利用[bx(si或di)+idata]的方式,来使程序变得简洁.如下:
codesg segment
start:mov ax,datasg
mov ds,ax
mov si,0
mov cx,8
s:mov ax,0[si]
mov 16[ax],ax
add si,2
loop s
mov ax,4c00H
int 21H
codesg ends
end start
