Assume指令解析

来源:互联网 发布:淘宝卖家发货短信提醒 编辑:程序博客网 时间:2024/06/05 16:53

刚学习80X86汇编的时候,有一条称为段分配伪指令Assume,我刚开始看这个的时候,就一直没看懂什么意思,老师也仅仅就说了一下,必须得这样,至于更深层次的讨论就没有,所以关于assume指令一直是懵懵懂懂的。这些天才回过头来看的话,貌似有一点感悟!很久没写点文章了,就写下自己对于assume的理解吧。

       很多书上说的是assume指令使段寄存器与某个段关联起来,但是assume指令是伪指令,还必须通过指令来赋值给段寄存器。这话第一次看的时候,确实很迷茫。在这里我试着从另外的一个角度去理解assume指令。

       还是先来个例子(为了突出重点,例子都是很简单,甚至仅为测试而写,没有实际意义)

DATA     SEGMENT              ;数据段

MESS    DB "HELLO",0DH,0AH,'$'

DATA     ENDS      

;

CODE     SEGMENT                   ;代码段

              ASSUME CS:CODE,DS:DATA          

START:   MOV AX,DATA

              MOV DS,AX

              MOV DX,OFFSET MESS

              MOV AH,9                          ;显示信息HELLO

              INT 21H

              MOV AH,4CH

              INT 21H                             ;返回DOS

CODE ENDS

              END START

在这个程序中,红色指令对应的是取得MESS的偏移地址,当我们对于MESS进行访问时候,汇编程序识别呢?我看可以这么理解哈,首先看到MESS的时候,汇编程序察觉这个是在DATA段中定义的变量,但是要访问它的时候,必须知道它的确切地址才行,所以在DATA段中,必须知道DATA的段地址,这个时候程序开始的前两条语句就已经给DS赋予了值,但是我们如何得知DSDATA的关系呢?这个时候就是assume的作用了,它就是告诉汇编程序,用指定的段寄存器寻址相应的逻辑段,建立段寄存器与段的默认关系。所以程序的开始用的是两个assume指令使代码段与数据段和指定的寄存器关联起来,程序的段地址知道了,偏移地址就是汇编程序地址计数器在进行汇编的时候自动算出来的,这个不用我们担心!

另外在dos装入EXE程序的时候,DSES被初始化为PSP(程序段前缀)的段地址,而不是用本身的数据段和附加数据段,所以源程序中必须重新初始化DSESCSIP指向源程序的代码段,cs必须被关联到指定的段,否则程序不能运行(代码段必须用ASSUME CSCODE指明,否则编译器不知道代码从何处开始执行,编译不通过)。SSSP指向程序的堆栈段,如果程序未设堆栈,则SSPSP的段地址加上256个字节,SP00h

上面说的可能还是不太清楚,写2个例子在下面看哈或许更明白些吧

DATA     SEGMENT              ;数据段

MESS    DB "HELLO",0DH,0AH,'$'

DATA     ENDS       ;

 

CODE     SEGMENT                   ;代码段

              ASSUME CS:CODE,ES:DATA    ;ES关联,一样的效果

; ASSUME CS:CODE,DS:DATA

             

START:   MOV AX,DATA

       MOV ES,AX        

       mov al,mess + 1

       or al,20h        ;大写变小写

       mov mess+1,al

 

       MOV AX,ES

       MOV DS,AX

       MOV DX,OFFSET MESS

       MOV AH,9                          ;显示信息HELLO

       INT 21H

       MOV AH,4CH

       INT 21H                             ;返回DOS

CODE ENDS

              END START

结果输出的是HeLLO

我们可以把红色代码换成ASSUME CS:CODE,DS:DATA,输出结果是HELLO,即没有变化。我们可以看下反汇编的代码就一切明白了。                                                       

 

没有改动的代码,可以看到访问变量mess的时候,自动加上了es段寄存器,这个就是assume的作用。如果改成ASSUME CS:CODE,DS:DATA,那么访问mess的话,则自动关联到ds寄存器,但是我们的程序中ds的值没有赋值,即ds的值还是原来程序段前缀的段地址,所以我们写的大小写转换不是在操作我们的数据,而是PSP中的某个数据。

 

相信说到这了,大家应该有一点稍微清晰的认识吧!

(原文参看了部分书籍的介绍)

原创粉丝点击