为什么每段开头都要有mov ax,data mov ds,ax两句,不是有assume定义过段了吗

可能是我表述得不够清晰,希望有善解人意的哥哥姐姐详细帮我解答下。

assume是伪指令,所谓的伪指令是形成上很类似于指令,但不属于CPU指令集,而是由汇编编译软件第一次扫描时,将伪指令转化为相应的指令。换句话来说,伪指令是属于汇编编译软件的,在编译时第一次扫描,会转成相应的指令集或是由编译软件执行某些操作。

即使是这样,伪指令也是最终操作了,这里应该好好理解一下assume伪指令,该指定是定义段的,比如定义一个数据段,该伪指令的目的就是对段的定义,并没有真正将段装载,如果汇编编译出来的程序相要执行,必须将段装载。也就是说,我们定义段了,但没有将段装载,相当于高级语言中定义了变量的类型,但没有进行赋值一样是不可用的。

而将段装载就是将段地址直接装配到ds寄存器中,将SP寄存器置0,然后会随着程序运行的变化sp不断地变化。那么,定义过段,必须还要进行装载,所以后边才会有:

mov ax,data
mov ds,ax
data就是定义过的段地址,该段地址会以相对地址转成内存的绝对地址装入,以便运行。因为内存地址不能直接装入到ds中,所以才会通过ax寄存器将段地址装载到ds中。

也就是说,伪指定assume只是将一个相对地址作为标号(如data)定义下来,而最终必须要装入段寄存器才可以运行的。追问

对于伪指令和指令,我还是很明白的。既然assume定义过段的类型了,编译后cpu就应该知道将各段地址装入对应的段寄存器啊,代码段不就是自动装入的么 - 3 -

追答

我懒汉你看没有看完,或是没有理解,也可能是一楼误导你了,伪指令只是编译器中定义的段,这根本不是运行程序中的段或段装入,当然还还可以这样理解:在开发的应该程序中根本不存在“段”,段只是人为的一个划分,数据只是从DS:SP中取出的,他并不管你哪个是段还是不是段,且定义有相应的操作,但不可能半段地址直接装入到DS中,因为运行时,不同的运行所占用的地址是不同的,要装入段地址的是相对于内存的绝对地址,上次运行与下次运行同一程序可能就会使用不同的内址地址。而定义段只是一个相同地址,也就是说,数据相对于运行程序所占用的内存的地址,但该应用程序会每次装入不同的内存地址。换句话来说,mov ax,data这些语句是在程序运行时才开始运行,而不是程序装载时直接运行的。这种情况下,比尔又能如何?

现在一个问题是:相对地址在程序未运行时如何将程序装入内存后的绝对地址装载?显然是不可能的!

温馨提示:内容为网友见解,仅供参考
第1个回答  2019-12-20
楼主的疑问是正确的。
这确实是个缺陷。
Intel 的指令集中,并没有这条。
微软的编译软件,才需要这条伪指令。
后来,微软推出的 MASM6.0,就可以免除这条伪指令了。
甚至于 SEGMENT/ENDS,这两句,都可以不要了。
早已经淘汰的指令,还有人为它辩解,真是奇了怪了。
现在的汇编语言教材上,仍然写这条指令吗?
王爽,真是毁人不倦、坑人不浅。
第2个回答  2011-09-20
assume,是伪指令,是对编译软件下的命令;
mov ax,data mov ds,ax两句,是指令,是对硬件进行操作。追问

assume定义段的作用不就是告诉cpu哪个段对应哪个段寄存器么,代码段的地址不是没有手动加载么,数据段为什么就要多此一举呢

追答

assume,是伪指令,是对编译软件下的命令,没有给CPU下命令。

程序开始时,DS需要用指令来装入段地址,CS不需要指令来装入段地址。
这些指令、伪指令的用法,都是当年微软公司规定的方法、步骤。

比尔●盖茨当年还很年轻,没有想到这些;
微软后来研发出来的,在WINDOWS环境下的编程软件,就没有这些让人质疑的地方。

我们作为使用者,按照它们规定的做法来做,就行了,不理解的,也不要瞎猜。
某些人的留言,好像是很懂,其实说的都是言而无据的话,误导他人而已。

第3个回答  2020-12-12
MOVDS,AX就是把ax的值放到段寄存器ds中一般dos程序的开头用movax,datasegmovds,ax这两句是让ds指向自己定义的数据段因为不能直接movds,dateseg,这样会出现语法错误,不能编译的
MOVDS,AX就是把ax的值放到段寄存器ds中一般dos程序的开头用movax,datasegmovds,ax这两句是让ds指向自己定义的数据段因为不能直接movds,dateseg,这样会出现语法错误,不能编译的
相似回答