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