当前位置: 代码迷 >> 汇编语言 >> assume到底有什么用处呢?该怎么处理
  详细解决方案

assume到底有什么用处呢?该怎么处理

热度:6607   发布时间:2013-02-26 00:00:00.0
assume到底有什么用处呢?
如  
assume   cs:data  
到底是什么意思呢?把段data和cs段寄存器联系起来  

是什么意思啊?能请大哥给个简单的例子和讲解么?

------解决方案--------------------------------------------------------
assume 是伪指令,只是给编译器看的,cpu并不会因为你用了assume cs:data就把data段和CS寄存器联系起来。如:
assume cs:data

data segment
db 0
data ends

code segment
start: ;重点在这里!
...

code ends
end start ;这里告诉编译器把初始化的ip放在start偏移处。


事实上我认为,assume的作用是当你在代码段中使用数据标号时才需要,如

assume cs:codesg,ds:datasg

datasg segment
str1 db 'a ', 'b ', 'c ' ;数据标号,注意这里没有 ": "号。
str2 db ' '
datasg ends

codesg segment
start:
mov ax,datasg
mov ds,ax ;寻址时默认还是要使用ds段寄存器

mov si,0
mov al,str1[si] ;这里如果不用assume ds:datasg的话编译器会找不到[SI]的地址。
mov str2[si],al


------解决方案--------------------------------------------------------
assume cs:data 是说 data 段由 cs 引用. 这个, 一般好像不对吧? cs 一般是指向代码段的, 如果代码段的段名就是 data 的话, 在不使用 ds 指向 data 时, 如果使用了 data 中的数据, 那么编译器能籍由 assume 语句给指令加上适当的段指令前缀:
data segment
value1 dw 1234h

start:
; ....
mov ax, value1 ; 这里, 最后的指令是 mov ax, cs:[value1]
; ....

data ends

现在的 assume 语句还有其它的功能, 比如设定一个类型:
assume eax, PTR RECT ; eax 是指向一个矩形结构的指针
mov ecx, [eax].left ; 籍该指针引用其 .left 成员
assume eax nothing ; 取消 eax 的类型, 避免后面对 eax 使用的误解
------解决方案--------------------------------------------------------
这个问题我曾经花费了很长时间才彻底搞清,当然搞不清楚也没有多大关系,只要用上
assume ds:data, cs:code ,es,edata就可以了
code,data,edata是你在程序中定义的逻辑段的名字,如果名字不同,上面的也要修改。作用如下:
data segment
value1 dw 1234h
data ends

code segment
mov ax,data
mov ds,ax
mov cx,value1;当程序执行到这里时,assume ds:data告诉编译器,到data段去找value1变量,找到后使用该变量的偏移地址。如果没有assume ds:data,编译器就不知道到哪个段去找value1变量。当然,如果编译器被设计得足够的聪明的话,就可以省略掉assume伪指令了。当然这都是微软开发人员研究出来的方法。
mov ax,4c00H
int 21H
code ends

cs:code 告诉编译器,源代码文件的指令序列放在了那个逻辑段,采用这种方法可以节省编译器的编译时间,如果把这个任务交给编译器,则需要增加一道扫描过程。除非把个逻辑段的名字规定成固定的名字,让编译器识别,但这样逻辑段的段名就失去了灵活性。简化段定义就不需要assume指令,它就是使用的固定段名实现的。堆栈段名和附加段名也是同样的原理,都是给编译器提供便利的,跟cpu毫无相干。