【问题标题】:moving data segment address DS via direct addressing mode通过直接寻址方式移动数据段地址 DS
【发布时间】:2016-02-01 14:25:39
【问题描述】:

在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           ; ???

有什么理由吗?

【问题讨论】:

    标签: assembly


    【解决方案1】:

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

    MOV AX,DTSEG
    MOV AX,OFFSET DATA
    

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

    LEA AX,DATA
    

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

    以下说明与您预期的不同:

    MOV AX,OFFSET DTSEG
    

    它使用 DTSEG 段开头的偏移量加载 AX,即 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 中的值,第二个示例加载存储在代码段中相同偏移量的任何内容。

    【讨论】:

    • 你为什么说“这些指令移动一个立即操作数......”。虽然 OFFSET DATA 是一个整数,但它指向一个内存位置。它不是立即数,例如 MOV AX,2
    • @mahmood 立即操作数是编码为指令一部分的操作数。它们是否应该表示地址对 CPU 没有影响。它只是使用编码到指令中的值作为操作数。
    • 请参阅goo.gl/eZGILc,其中的数据来自 W. Treibel 的 8086 编程和界面手册。另外,请查看goo.gl/VRNlDR,在第一页和第二页中,它显示了一些有关模式的示例。
    • 如您所见,在MOV AX,OFFSET DATA中,如果DATA的位置是10h,那么我们将第十个位置的内容移动到AX,即MOV AX,[10h]。所以我不同意你的观点,即 OFFSET 意味着立即模式。在我看来,偏移量是有效地址。不是吗?
    • @mahmood 他们最终做同样的事情。那是因为 LEA 以通常的方式使用它的内存操作数。它不是加载存储在内存操作数中的值,而是加载内存操作数的偏移量。使用MOV, AX, OFFSET DATA,DATA 的值被编码为立即操作数。对于MOV AX, DATALEA AX, DATA,DATA 的值被编码为内存操作数中的位移。想想MOV AX, [DATA + BX]LEA AX, [DATA + BX] 可能会有所帮助。两者都将 DATA 编码为位移,但只有前者从内存中读取。后者以 DATA 加 BX 的偏移量加载 AX。
    猜你喜欢
    • 2012-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-09
    • 1970-01-01
    • 1970-01-01
    • 2011-05-21
    相关资源
    最近更新 更多