汇编学习 16 直接定址表

1.小思考:为什么我们需要assume字段?

  • 一句话:assume可以关联不同的段和寄存器,可以改变相应段中的标号所默认关联的段寄存器,但是不能实际改变寄存器的值
  • 什么意思?这一节我们学习了数据标号,数据标号可以这样使用:
mov ax,a[si] ; a定义在data segment中,data段同ds关联

数据标号a,可以直接作为一个地址,同时还可以表示数据大小。我们设想一下编译器是如何翻译这段代码的:首先它看到了标志a,寻找标志a的位置,结果在data segment中找到了a的标志,然后它寻找data段所关联的寄存器ds,然后它就会把汇编代码看成这样:

mov ax,ds:offset a[si] ; 这里只是为了方便说明的假设

这样编译器也就准确找到了标志a的位置,但是ds的值究竟是多少,真的是data段的段地址吗?编译器不知道,需要人为设定:

mov ax,data
mov ds,ax

这样才让编译器真的找对了数据标志的地方。所以assume字段修改了编译器翻译出来的代码,而段寄存器实际的值,assume是修改不了的,需要手动修改。

所以我们进一步思考,一般来说我们都会在开始的地方加上assume cs:code 这一句话,如果不加会有什么后果?
》》》编译器在执行code段的代码时,如果遇到类似jmp S这样的代码时,S实际上代表着一个偏移地址,那段地址在哪里寻找?如果关联了cs和code字段,因为S是出现在code段的,自然段地址就是cs了,编译器可以正确找到;如果没有关联,遇到code中有一个S标号,编译器根本就不知道在那个段寄存器找到段地址,自然编译也就不会成功。

2.数据标号

  • 有一种标号,这种标号不但表示内存单元的地址,还表示内存单元的长度,也就是表示在此标号处的单元,是一个字节单元,还是字单元,还是双字单元。
    比如:
code segment
a db 1,2,3,4,5,6,7,8
b dw 0
...
code ends

比如标号a,描述了地址code:0,和从这个地址开始,以后内存单元都是字节单元两个信息;标号b,描述了从code:8开始,并且以后内存单元都是字单元

  • 使用数据标号注意操作数匹配问题,不能操作大小不同的数
mov b[2],al
mov ax,a[3]
; 以上表示都是错的,b匹配的是字单元,不能与al搭配;a匹配的是字节单元,不能与ax寄存器搭配

!补充:在其他段中使用数据标号
如果在其他段中使用数据标号,一定要将assume字段中将对应的段和某个寄存器联系起来,否则在使用数据标号的时候,CPU会因为找不到相应的段寄存器而出错!(在小思考中解释了相应的原因)

3.直接定址表(一种映射关系表)

总述:利用直接定址表,我们可以将两个数据集之间建立一种映射关系,我们可以用查表的方法根据 给出的数据,在另一个集合中得到对应数据。
我们利用直接定址表,一般来说有三个目的:

(1)提高算法的清晰程度和简洁程度
(2)为了加快运算速度
(3)为了使程序更易于扩充

你可能感兴趣的:(汇编学习 16 直接定址表)