段寄存器的两种初始化方式

  实模式(real mode)下采用段地址:偏移地址的方式进行定位。在Masm中,有2种方式对段地址进行初始化,一就是编译阶段,再就是程序执行阶段。

  一、汇编阶段(Masm编译阶段):

  汇编阶段通过Assume伪指令对段段寄存器的值进行指定(但并不对段寄存器真的赋值),而是按Assume指定的情况进行编译。比如,在对标号进行编译的时候,就根据Assume CS的值进行计算,如Assume中指定的段没有相应的标号,则会提示错误;还有就是有多个代码段的时候,要在适当的时候切换。其他在汇编阶段需要段寄存器的情况我暂时还想不出,请指定的朋友告知一下,非常感谢!

  Assume 语法:

  Assume segementregister:name[,segementregister:name]

  Assume segementregister:nothing(取消指定)

  Assume nothing(取消所有指定)

  1、name的值可以是段名称、组名称、seg表达式或计算后为段名称或组名称的字符串。

  2、assume可以在任何地方指定,如果重新指定(再次assume),之后的代码的段寄存器已重新指定为准。

  二、程序执行阶段(Dos载入exe后,执行exe阶段):

  程序执行阶段段寄存器的值得初始化真实赋值给段寄存器的,而不是assume那样假定。

  1、CS和IP寄存器:

   CS和IP寄存器的值都是在exe文件的psp段中进行初始化,即系统载入exe文件时初始化。psp中,CS的值是通过End [StartAddress]伪指令确定的。StartAddress可以是标号或表达式。IP得值基本都是0,可通过ORG指令修改,如com文件的ORG 100h。如果exe文件由多个obj文件组成,只能有一个文件指定CS的值,就像C语言只有一个main函数一样,程序只能有一个起始地址。
  2、SS和SP寄存器:

  SS和SP寄存器也是在PSP中初始化(同上)。PSP中,SS和SP是通过类型为STACK的段定义计算并赋值,SS对应段地址,SP指向段的尾部。

  3、DS寄存器:

  DS寄存器并不通过PSP初始化,必须通过代码,所以大部分汇编程序前几行的代码都是对DS进行初始化,如:

mov ax,_DATA
mov ds,ax

  8086后续的ES、GS则同样需要通过代码进行初始化。

  ☆对于exe文件中的段地址,都只是相对地址。系统在加载exe文件时,都会在相对地址的基础上,对相对地址进行重定位,即替换成物理地址,其他相对于段地址的偏移地址则无需处理。

posted @ 2022-10-31 17:49  美洲象  阅读(435)  评论(0编辑  收藏  举报