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

发布于 2024-10-23 01:00:47 字数 961 浏览 3 评论 0原文

谁能解释一下这三个指令的功能吗?

  ORG 1000H 
  MOV AX,CS
  MOV DS,AX

我知道理论上代码、数据和额外段是什么,但是:

  1. 它们是如何在这个程序中实现的?

  2. 为什么整个段被移到另一个段中? (MOV AX,CSMOV DS,AX

这两条指令实际上做什么

除了突出显示的 3 条指令之外,我可以理解此代码中其他所有指令的含义。

(程序工作正常。它接受输入,直到命中 0 - 有一个 mov ah,01h 和一个 int 21h,然后比较 al'0',如果al'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 程序。该程序不会中断,因为它不使用任何绝对值。地址,仅相对跳转。)

Can someone please explain the functions of these three instructions?

  ORG 1000H 
  MOV AX,CS
  MOV DS,AX

I know what the code, data, and extra segments are in theory, but:

  1. How they are implemented in this program?

  2. Why is the entire segment moved into another? (MOV AX,CS and MOV DS,AX)

What do these two instructions actually do?

I can understand the meaning of every other instruction in this code, except for the highlighted 3 instructions.

(The program works fine. It accepts input till 0 is hit -- there's a mov ah,01h and an int 21h, then it compares al to '0' and if al is '0', it jumps to last, otherwise it jumps into 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

(Editor's note: .com programs are loaded at offset 100h, with all segment registers set equal to each other. org 1000h is likely a typo for org 100h because this looks like a .com program. This program doesn't break because it doesn't use any absolute addresses, only relative jumps.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

别挽留 2024-10-30 01:00:47

为了真正解释这个概念,我们必须回顾段的基本概念,以及 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

To really explain the concept, we have to back up to the basic idea of segments, and how the x86 uses them (in real mode).

The 8086 has 20-bit addressing, but only 16-bit registers. To generate 20-bit addresses, it combines a segment with an offset. The segment has to be in a segment register (CS, DS, ES, or SS). You then generate an offset (as an immediate value, or the contents of another register or two.

So, to generate an address, a 16-bit segment register is shifted left four bits, and then a 16-bit offset in some other register is added to that, and the combined total is actually used as the address. Most instructions have a default segment attached to them -- push, pop and anything relative to bp will use ss. Jumps and such use cs. Some of the string instructions es (e.g., scans) and some use use two segments -- for example, movsd copies data from [ds:si] to [es:di]. Most other instructions use ds. You can also use segment overrides to explicitly specify an address like es:bx.

In any case, before you can make any meaningful use of a segment register, you first have to load it with the (top 16 bits of) the address of the data you care about. A typical "small model" program will start with something like:

mov ax, @Data
mov ds, ax

In tiny model, you use the same segment for the data and the code. To make sure it's referring to the correct segment, you want to get the 16 bits from CS and copy it to DS. As a number of others have mentioned, there's no instruction to move CS directly to DS. The question mentions one possibility; another common one is:

push cs
pop ds
盛夏尉蓝 2024-10-30 01:00:47

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

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

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

ORG 1000H tells the assembler that the code that follows should be placed at offset 1000H in the code image.

The other two instructions copy CS to DS. It is not copying the segment itself, just updating the pointer to the data segment. For a small program (<64K), static data (string literals in the source, indirect jump tables) may be placed together in the same segment with the code. The segment base pointer needs to be loaded in DS before accessing the static data. The loader (the part of the OS that reads the program from disk to memory and starts it running) has to set CS so that it can run the program, but may not set DS, so the program copies CS to DS when it starts.

The two instruction sequence is needed because "MOV DS, CS" is not a legal 8086 instruction.

安静 2024-10-30 01:00:47

你不能这样做,

MOV DS, CS

这是一个无效的操作(masm 32:错误A2070:无效的指令操作数)。

MOV AX, CS
MOV DS, AX

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

you can't do

MOV DS, CS

it's an invalid operation (masm 32: error A2070: invalid instruction operands).

MOV AX, CS
MOV DS, AX

These 2 instruction perform the same as mov ds, cs (which is invalid). This way the assembler is happy and doesn't complain. But I can't tell you why the programmer wants the data segment to be the same as the code segment

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文