多种寻址方式定位内存地址

骑猪看日落 2021-05-03 16:07 655阅读 0赞

当数据存放在内存中时,我们可以使用多种方式来给定这个内存单元的偏移地址,这种定位内存单元的方法被称为寻址方式。
这里写图片描述

1. 直接寻址

寻址方式:
[idata]
含义:
EA=idata
寻址过程:
例: 上图中的 mov ax,ds:[000E]
CS和IP中的地址通过地址加法器进行移位相加得到代码的物理地址,通过地址总线进入内存,取出相应地址的机器码000EA1,通过数据总线传到指令缓冲寄存器,读取指令判断是直接寻址,则通过段地址ds和偏移地址[000E]得到数据的物理地址,在内存中取出。

2.寄存器间接寻址

寻址方式:
[bx]
含义:
EA=(bx)
寻址过程:
例: 上图中的 mov ax,[bx]
CS和IP中的地址通过地址加法器进行移位相加得到代码的物理地址,通过地址总线进入内存,取出相应地址的机器码078B,通过数据总线传到指令缓冲寄存器,读取指令判断是寄存器间接寻址,则通过段地址ds和寄存器BX提供的偏移地址得到数据的物理地址,在内存中取出。

3.寄存器相对寻址

寻址方式:
[bx+idata]
含义:
EA=(bx)+idata
寻址过程:
例: 上图中的 mov ax,[bx+1]
CS和IP中的地址通过地址加法器进行移位相加得到代码的物理地址,通过地址总线进入内存,取出相应地址的机器码01478B,通过数据总线传到指令缓冲寄存器,读取指令判断是寄存器相对寻址,则通过段地址ds和寄存器BX提供的内容加上一得到偏移地址从而得到数据的物理地址,在内存中取出。

4.基址变址寻址

寻址方式:
[bx+si] ; [bx+di]
含义:
EA=(bx)+(si) ; EA=(bx)+(di)
可以表示为[bx][si],相当于一个二维数组
寻址过程:
例: 上图中的 mov ax,[bx+si]
CS和IP中的地址通过地址加法器进行移位相加得到代码的物理地址,通过地址总线进入内存,取出相应地址的机器码008B,通过数据总线传到指令缓冲寄存器,读取指令判断是基址变址寻址,则通过段地址ds和寄存器BX提供的内容加上源寄存器SI提供的内容得到偏移地址从而得到数据的物理地址,在内存中取出。

5.相对基址变址寻址

寻址方式:
[bx+si+idata] ; [bx+di+idata]
含义:
EA=(bx)+(si)+idata ; EA=(bx)+(di)+idata
寻址过程:
例: 上图中的 mov ax,[bx+si+1]
CS和IP中的地址通过地址加法器进行移位相加得到代码的物理地址,通过地址总线进入内存,取出相应地址的机器码01408B,通过数据总线传到指令缓冲寄存器,读取指令判断是相对基址变址寻址,则通过段地址ds和寄存器BX提供的内容加上源寄存器SI提供的内容再加上一得到偏移地址从而得到数据的物理地址,在内存中取出。

6.为什么我们需要这么多的寻址方式

这是为了在效率和方便性上找一个平衡。立即数寻址和寄存器寻址在效率上是最快的,但寄存器仅有几个非常宝贵不可能将操作数都存入其中等待使用,立即数的使用场合也非常有限,这样就需要将数据保存在内存中,然后使用直接寻址、寄存器间接寻址、寄存器相对寻址、基址加变址寻址、相对基址加变址寻址这些寻址方式将内存中的数据移入寄存器中。

7.应用举例

问题1:编程将datasg段中每个单词的头一个字母改为大写字母。
assume cs:codesg,ds:datasg
datasg segment
db ‘1. file ’
db ‘2. edit ’
db ‘3. search ’
db ‘4. view ’
db ‘5. options ’
db ‘6. help ’
datasg ends
codesg segment
start: ….…
mov 4c00h
int 21h
codesg ends
end start
这里写图片描述
注意这里定义的字符串后面是有空格个,凑成的一行16个字节

直接寻址方式
[bx+idata] 起始bx设为0,为第一行第一个单元的地址,idata设为3,表示这一行第三个单元即单词首字母

  1. mov ax,datasg
  2. mov ds,ax
  3. mov bx,0
  4. mov cx,6 ;循环六次
  5. s: mov al,[bx+3]
  6. and al,11011111b ;与运算,小写变成大写
  7. mov [bx+3],al
  8. add bx,16 bx16,跳到下一行开始位置

问题2:编程将datasg段中每个单词改为大写字母
assume cs:codesg,ds:datasg
datasg segment
db ‘ibm ’
db ‘dec ’
db ‘dos ’
db ‘vax ’
datasg ends
codesg segment
start: ……
codesg ends
end start
这里写图片描述
注意这里定义的字符串后面是有空格个,凑成的一行16个字节

寄存器间接寻址二重循环
4 个字符串,可以看成一个 4行16列的二维数组,要修改二维数组的每一行的前3列,则构造4x3次的二重循环

  1. mov ax,datasg
  2. mov ds,ax
  3. mov bx,0
  4. mov cx,4
  5. s0: mov si,0
  6. mov cx,3
  7. s: mov al,[bx+si]
  8. and al,11011111b
  9. mov [bx+si],al
  10. inc si
  11. loop s ;内层循环
  12. add bx,16
  13. loop s0 ;外层循环

但是这样做只有一个cx,执行完内层循环后就变成0了,无法完成外层循环
这里可以用栈保存cx

  1. stacksg segment
  2. dw 0,0,0,0,0,0,0,0
  3. stacksg ends
  4. mov ax,stacksg
  5. mov ss,ax
  6. mov sp,16
  7. mov ax,datasg
  8. mov ds,ax
  9. mov bx,0
  10. mov cx,4
  11. s0: push cx ;将外层循环的cx值压栈
  12. mov si,0
  13. mov cx,3 ;cx设置为内存循环的次数
  14. s: mov al,[bx+si]
  15. and al,11011111b
  16. mov [bx+si],al
  17. inc si
  18. loop s
  19. add bx,16
  20. pop cx ;从栈顶弹出原cx的值,恢复cx
  21. loop s0

发表评论

表情:
评论列表 (有 0 条评论,655人围观)

还没有评论,来说两句吧...

相关阅读

    相关 CPU范围(空间)

    一、什么叫寻址空间?          寻址空间一般指的是CPU对于内存寻址的能力。通俗地说,就是能最多用到多少内存的一个问题。数据在存储器(RAM)中存放是有规律的 ,CP