谁能解释一下这三个指令的功能吗?
ORG 1000H
MOV AX,CS
MOV DS,AX
理论上我知道代码、数据和额外的段是什么,但是:
它们在这个程序中是如何实现的?
为什么整个段被移到另一个段中? (MOV AX,CS
and MOV DS,AX
)
这两条指令的作用是什么实际上做?
除了突出显示的 3 条指令之外,我可以理解此代码中其他所有指令的含义。
(程序工作正常。它接受输入直到 0 被击中——有一个mov ah,01h
and an int 21h
,然后比较al
to '0'
and if al
is '0'
,它跳转到last
,否则它会跳入back
.)
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
(编者注:.com
程序在偏移处加载100h
,所有段寄存器设置为彼此相等。org 1000h
可能是一个拼写错误org 100h
因为这看起来像.com
程序。该程序不会中断,因为它不使用任何绝对地址,仅使用相对跳转。)
为了真正解释这个概念,我们必须回顾段的基本概念,以及 x86 如何使用它们(在实模式下)。
8086有20位寻址,但只有16位寄存器。为了生成 20 位地址,它将段与偏移量组合起来。该段必须位于段寄存器(CS、DS、ES 或 SS)中。然后生成一个偏移量(作为立即值或另一个或两个寄存器的内容)。
因此,为了生成地址,将 16 位段寄存器左移 4 位,然后将其他寄存器中的 16 位偏移量添加到其中,合并后的总和实际上用作地址。大多数指令都附加了一个默认段——push
, pop
以及任何与bp
将使用ss
。跳跃等使用cs
。一些字符串指令es
(e.g., scans
),有些使用两个段——例如,movsd
从复制数据[ds:si]
to [es:di]
。大多数其他指令使用ds
。您还可以使用段覆盖来显式指定地址,例如es:bx
.
无论如何,在对段寄存器进行任何有意义的使用之前,您首先必须向其加载您关心的数据的地址(前 16 位)。典型的“小模型”程序将从以下内容开始:
mov ax, @Data
mov ds, ax
在微型模型中,您对数据和代码使用相同的段。为了确保它引用正确的段,您需要从 CS 获取 16 位并将其复制到 DS。正如许多其他人所提到的,没有任何说明可以将 CS 直接移至 DS。这个问题提到了一种可能性;另一个常见的是:
push cs
pop ds
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)