CSDN=>FAQ=>FAQ 展示
  • 问题内容:伪指令assume的作用是什么?
  • 原讨论链接:http://community.csdn.net/expert/topicview1.asp?id=5111621
  • 所属论坛:汇编语言     审核组:其他开发语言
  • 提问者:blackchoc     解决者:fanxero
  • 感谢:
  • 关键字:字段 其他开发语言 汇编语言 内存 程序 地址 操作系统 编译 指令 起始 偏移
  • 答案:

    伪指令assume的作用是什么?不是将相应的程序入口地址给寄存器吗?
    为什么我写的程序必须等到运行到
    mov ax,DATA    ;DATA是数据段的开始地址
    mov ds,ax
    结束的时候,ds的值才能真正显示。
    否则如果在程序的一开始就使用-d ds:0
    查看的结果总是2049。

    assume 既然已经设置了ds:DATA cs:CODE
    为什么在代码中还要再写
    mov ax,DATA
    mov ds,ax
    这样的工作呢?
    这样的话要伪指令assume还有什么用处呢???

    系统在分配内存空间的时候不是在没有执行任何指令的时候就已经分配好了吗??

    ---------------------------------------------------------------

    dos下连编生成的汇编程序有两种,扩展名分别为com和exe。
    com程序是纯cpu指令和数据,在磁盘上放着的com文件和被加载到内存后内容是一样的,cpu按照IP指示的第一条指令开始执行。com程序只能在一个64K的段中执行,它的代码啊数据啊什么东西全都在这一个64K以内的段中。但是想想,程序功能多了,或需要的处理的数据多了,那这一个段怎么够用啊,于是有了exe文件。exe程序分成好多段,有放代码的,有放数据的,那好这么一个exe程序连编完成了,把它放到内存里运行,你想想这exe程序分了几个段,该用到哪个段时,程序是怎么找它们的地址呢?com文件好说,用哪谁就jmp过去了,反正就在一个64K的段里面,但是exe不行了,你不给它讲要用的那个段的段地址,它就没法过去啊。于是需要有个东西给它指示段地址。于是有人说了,不是有assume指示段地址吗?但事实上在程序运行前是有些情况下是无法确定段地址的。因为你不知道操作系统把你的exe程序加载到哪里去运行。换句话说,操作系统有可能会把你加载到A地址开始执行,下次就有可能会把你加载到B地址去执行,这跟操作管理内存的方式和操作系统运行状态有关。那么这个段地址该由谁指示啊?答案是操作系统!操作系统决定你的程序里各个段的段地址。但是又有人会说了,操作怎么知道我有几个段啊,每个段又干什么啊。这个信息是由exe文件头部提供的。exe文件头部是一个数据结构,里面包括一个重定位表,重定位表的作用就是给出程序代码段里各个需要修改地址的项。
    举例来说吧。
    比如你程序里有这么几句
    data segment
    ……
    data ends

    code segment
    start:
    mov ax,data
    mov ds,ax
    ……
    code ends
    end start
    假如说在生成的exe文件头里的重定位表中有一项是0000:0030,0000H是高字段,0030H是低字段。用高字段加上起始段值,也就是exe文件加载到内存里的起始地址段(假如是1000H),则结果为1000H,再加上低字段作为偏移量,则结果为10030H,这个20位的地址指向内存地址为10030H的单元。把指向的这个地址里的字取出来(假设是0010H),加上起始段值,再放回去。这就完成了一次重定位。即10030H里存放的是1010H。
    你可以用debug跟踪你的程序,在执行到mov ax,data时,这条指令的操作数字段就是1010。在进行重定位之前操作数字段一直为0010H。
    经过了重定位,才能真正地获得段地址。
    分析一下重定位做了些什么:涉及段的地址的操作,一般都会用到重定位。比如mov ax,data,在编译阶段,编译器无法确定程序运行时段地址,于是在用到段地址时那个数据里都填入段地址相对程序开始的偏移,连接程序生成exe文件头,里面的重定位表记录了,哪个字需要修正。程序加载到内存后,操作系统在程序运行前要进行调整,进行程序重定位。把定位表中高字加上程序在内存中起始的位置,这个就指定了要改的那个地址所在的段地址,再加上那个地址在所在段里的偏移,就是重定位表项里的低字,这样就取得了需要重定位的那个单元,它里面放的是编译阶段写进去的,该地址相对程序起址地址的偏移,把这个偏移加上程序起始段址就得到了该单元真正的指向的地址。
    我晕,我越说越乱了,希望对楼主有帮助,能看懂吧。
    总而言之,assmue是告诉编译器是各个段是什么用途的,什么性质的。并没有分给他们地址,而且也无法知道运行时地址是什么。
    真正给真正地址的是mov ax,data这类型的,data里放的是修正了的真正的段地址。
    其实好多功能是要操作系统帮助下才能运行的,如果在裸机情况下运行只有com文件了。

  • 评价: 有价值 给朵鲜花(18) 无价值 扔个鸡蛋(4)
相关FAQ
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo