关于伪指令 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
              <font color="#0000dd">
              MOV DX,OFFSET MESS
              </font>
              MOV AH,9                          ;显示信息HELLO
              INT 21H
              MOV AH,4CH
              INT 21H                             ;返回DOS
CODE ENDS
              END START

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

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

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

DATA     SEGMENT              ;数据段
MESS    DB "HELLO",0DH,0AH,'$'
DATA     ENDS       ;

CODE     SEGMENT                   ;代码段
         <font color="#0000dd">
         ASSUME CS:CODE,ES:DATA    ;用ES关联,一样的效果
         </font>
; 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中的某个数据。

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

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇