MOV AX,CS和MOV DS,AX的概念

时间:2011-03-19 19:12:39

标签: assembly x86-16

有人可以解释三条指令的功能......

>      ORG 1000H 
>      MOV AX,CS
>      MOV DS,AX

我知道什么是代码,数据,理论上的额外片段。

但是,

1.他们如何在这些计划中实施?

2.为什么他们将整个段移动到另一段?(MOV AX,CS; MOV DS,AX;

(对不起,如果问题很荒谬)这2条指令的真实概念是什么......

  

/ *下面给出的汇编程序   8086效果很好。

     

我能理解每一个人的意思   本代码中的说明,

     

除了突出显示的3条指令外。   * /

代码接受输入,直到0被击中!

Code:
    ASSUME CS:CODE        
    CODE SEGMENT 
    ORG 1000H
    MOV AX,CS
    MOV DS,AX
BACK:
   MOV AH,01H
   INT 21H
   CMP AL,'0'
   JZ LAST
   JMP BACK
LAST:
   MOV AX,4C00H
   INT 21H
   CODE ENDS

   END

3 个答案:

答案 0 :(得分:9)

为了真正解释这个概念,我们必须回到段的基本思想,以及x86如何使用它们(在实模式下)。

8086具有20位寻址,但只有16位寄存器。要生成20位地址,它会将段与偏移量组合在一起。该段必须位于段寄存器(CS,DS,ES或SS)中。然后生成一个偏移量(作为立即值,或另一个或两个寄存器的内容。

因此,为了生成一个地址,一个16位的段寄存器向左移位四位,然后在其他寄存器中添加一个16位的偏移量,并且实际上将组合的总数用作地址。大多数说明都附加了默认细分 - pushpop,与bp相关的任何内容都将使用ss。跳转和使用cs。一些字符串说明es(例如,scans)和一些使用两个段 - 例如,movsd将数据从[ds:si]复制到[es:di]。大多数其他说明使用ds。您还可以使用段覆盖来明确指定es:bx等地址。

在任何情况下,在您可以有意义地使用段寄存器之前,首先必须使用您关注的数据的地址(前16位)加载它。一个典型的“小模型”程序将从以下内容开始:

mov ax, @Data
mov ds, ax

在小型模型中,您对数据和代码使用相同的段。要确保它指的是正确的段,您需要从CS获取16位并将其复制到DS。正如其他许多人所提到的那样,没有指令将CS直接转移到DS。这个问题提到了一种可能性;另一个常见的是:

push cs
pop ds

答案 1 :(得分:8)

ORG 1000H告诉汇编程序,后面的代码应放在代码映像中的偏移量1000H处。

另外两条指令将CS复制到DS。它不是复制段本身,只是更新指向数据段的指针。对于小程序(< 64K),静态数据(源中的字符串文字,间接跳转表)可以与代码一起放在同一段中。在访问静态数据之前,需要在DS中加载段基指针。加载程序(从磁盘到内存读取程序并启动它运行的操作系统的一部分)必须设置CS以便它可以运行程序,但可能不设置DS,因此程序在启动时将CS复制到DS。

需要两个指令序列,因为“MOV DS,CS”不是合法的8086指令。

答案 2 :(得分:1)

你做不到

MOV DS, CS

这是一个无效的操作(masm 32:error A2070: invalid instruction operands)。

MOV AX, CS
MOV DS, AX

这两条指令的执行与mov ds, cs相同(无效)。这样装配工很高兴并且不会抱怨。但我不能告诉你为什么程序员希望数据段与代码段相同