8086汇编-34更灵活定位内存地址03

#pragma once

/*34-更灵活定位内存地址03

SI和DI

SI和DI是8086CPU中和BX功能相近的寄存器,但是SI和DI不能够分成两个8 位寄存器来使用。 (就是不能像AX,BX,CX,DX 通用寄存器一样 拆分出高位和低位)

SI和DI是又叫-- (SI)源变址寄存器 和 (DI)目的变址寄存器,其作用就是用来存放"偏移地址"的,所以说是和BX功能相近的寄存器,而且这两个也是通用寄存器,只是不能拆分成8位寄存器而已,注意从这里开始我们就已经学习

了6个通用寄存器了!!!

下面的三组指令实现了相同的功能:

(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]

问题

用寄存器SI和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 指向复制的目的空间,然后用一个循环来完成复制。

SI和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次。

问题

用更少的代码,实现上一个问题的程序。

思考后看分析。

联系上节课的方法。

问题分析

我们可以利用[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[si],ax
                     add si,2
                     loop s
                     mov ax,4c00h
                     int 21h
            codesg ends
            end start

[bx+si]和[bx+di]

在前面,我们用[bx(si或di)]和[bx(si或di)+idata] 的方式来指明一个内存单元,我们还可以用更灵活的方式:

[bx+si]

[bx+di]

[bx+si]和[bx+di]的含义相似,我们以[bx+si]为例进行讲解。

[bx+si]表示一个内存单元,它的偏移地址为(bx)+(si)(即bx中的数值加上si中的数值)。

我们看下指令mov ax,[bx+si]的含义:

将一个内存单元的内容送入ax,这个内存单元的长度为2字节(字单元),存放一个字,偏移地址为bx中的数值加上si中的数值,段地址在ds中。

指令mov ax,[bx+si]的数学化的描述为:

(ax)=( (ds)*16+(bx)+(si) )

该指令也可以写成如下格式(常用):

mov ax,[bx][si]

问题

用Debug查看内存,结果如下:

2000:1000 BE 00 06 00 00 00 ……

写出下面的程序执行后,ax、bx、cx中的内容。

         mov ax,2000H
         mov ds,ax
         mov bx,1000H
         mov si,0
         mov ax,[bx+si]
         inc si
         mov cx,[bx+si]
         inc si
         mov di,si
         add ax,[bx+di] ; 思考后看分析。

分析

mov ax,[bx+si]

访问的字单元的段地址在ds中,(ds)=2000H;

偏移地址=(bx)+(si)=1000H;

指令执行后(ax)=00BEH。

mov cx,[bx+si]

访问的字单元的段地址在ds中,(ds)=2000H;

偏移地址=(bx)+(si)=1001H;

指令执行后(cx)=0600H。

add cx,[bx+di]

访问的字单元的段地址在ds中,(ds)=2000H;

偏移地址=(bx)+(di)=1002H;

指令执行后(cx)=0606H。

[bx+si+idata]和[bx+di+idata]

指令mov ax,[bx+si+idata]:

该指令也可以写成如下格式(常用):

       mov ax,[bx+200+si]  
       mov ax,[200+bx+si]  
       mov ax,200[bx][si]  
       mov ax,[bx].200[si]  
       mov ax,[bx][si].200

问题

用Debug查看内存,结果如下:

2000:1000 BE 00 06 00 6A 22 ……

写出下面的程序执行后,ax、bx、cx中的内容。

         mov ax,2000H
         mov ds,ax
         mov bx,1000H
         mov si,0
         mov ax,[bx+2+si]
         inc si
         mov cx,[bx+2+si]
         inc si
         mov di,si
         mov bx,[bx+2+di]  思考后看分析。

问题分析

mov ax,[bx+2+si]

访问的字单元的段地址在ds中,(ds)=2000H;

偏移地址=(bx)+(si)+2=1002H;

指令执行后(ax)=0006H。

mov ax,[bx+2+si]

访问的字单元的段地址在ds中,(ds)=2000H;

偏移地址=(bx)+(si)+2=1003H;

指令执行后(cx)=006AH。

mov ax,[bx+2+si]

访问的字单元的段地址在ds中,(ds)=2000H;

偏移地址=(bx)+(si)+2=1004H;

指令执行后(cx)=226AH。

*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值