通过直接寻址模式移动数据段地址DS

时间:2015-11-01 17:43:47

标签: assembly

在X86汇编语言中,为了将数据段的起始地址移动到数据段寄存器,必须先将其移至AX,然后将AX移至DS }。像这样:

DTSEG     SEGMENT
 ...
DTSEG     ENDS
CDSEG     SEGMENT
MAIN      PROC   FAR
          MOV    AX,DTSEG
          MOV    DS,AX
CDSEG     ENDS
          END    MAIN

我想知道,我们在第一行使用直接寻址模式吗?现在考虑,我们在数据段中定义一个字符串字节,如此

DTSEG     SEGMENT
DATA      DB        'HELLO'
DTSEG     ENDS

这次,我们必须使用MOV AX,OFFSET DATALEA AX,DATA加载有效地址。它们都有效。现在,第二个问题是我们仍然使用直接寻址模式吗?

然后,第三个问题是为什么我们不加载数据段的有效地址?像这样:

MOV    AX,OFFSET DTSEG    ; ???
LEA    AX,DTSEG           ; ???

有什么理由吗?

1 个答案:

答案 0 :(得分:4)

以下几行不使用寻址模式。寻址模式仅用于存储器操作数,这些指令将立即操作数移入寄存器操作数:

MOV AX,DTSEG
MOV AX,OFFSET DATA

只有以下指令有内存操作数,是的,它使用直接寻址:

LEA AX,DATA

通常,内存操作数指示内存中指令读取和/或写入的位置,但LEA指令不同。而是将存储器操作数的位置的偏移(地址)加载到寄存器中。

以下说明并不符合您的预期:

MOV AX,OFFSET DTSEG

它将AX加载DTSEG段开头的偏移量,即0。

以下说明无效:

LEA AX, DTSEG

您不能将段用作内存操作数。

您的大多数误解都来自16位实模式代码中分段寻址的工作原理。每个内存操作数通过段和偏移对引用内存中的位置。段和偏移都是16位值,并且它们通过将段部分乘以16并将其添加到偏移来组合以形成20位地址。访问数据时,段部分始终来自段寄存器,通常隐含地是DS寄存器。偏移部分通常明确地作为内存操作数给出。

例如:

CDSEG SEGMENT
     mov  ax, DTSEG
     mov  ds, ax
     mov  bx, OFFSET DATA
     mov  ax, [bx]
     mov  dx, cs:[bx]
CDSEG ENDS

指令mov ax, [bx]加载存储在段DTSEG中的偏移DATA处的16位值。指令mov ax, cs:[bx]加载存储在段CDSEG的偏移DATA处的16位值。第一个示例加载存储在DATA中的值,第二个示例加载发生在代码段中相同偏移处的任何内容。