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

标签 assembly x86-16 real-mode memory-segmentation

有人可以解释一下这三个指令的功能吗?

  ORG 1000H 
  MOV AX,CS
  MOV DS,AX

我知道理论上的代码、数据和额外段是什么,但是:
  • 在这个程序中它们是如何实现的?
  • 为什么整个段移动到另一个? ( 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 程序。该程序不会中断,因为它不使用任何绝对地址,只有相对跳转。)

    最佳答案

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

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

    因此,为了生成地址,将 16 位段寄存器左移 4 位,然后将其他寄存器中的 16 位偏移量添加到其中,合并的总数实际上用作地址。大多数指令都有一个默认的段 - push , pop以及与 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
    

    关于assembly - MOV AX,CS 和 MOV DS,AX 的概念,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5364270/

    相关文章:

    assembly - 如何在多核处理器上进行基准测试

    无法在 C 中写入屏幕内存

    string - 子字符串搜索程序总是返回 false

    assembly - 如何在 MOV 和 LEA 指令后确定 AX 中的结果

    assembly - 无法在 16 位实模式汇编中清除整个屏幕

    assembly - Turbo 汇编器多输入重叠

    assembly - x86 MASM 程序集 - 保存字符串的空变量

    c - 在 64 位汇编中编写函数

    c - 有针对 8086 的 C 编译器吗?

    assembly - 如何在 16 位汇编中执行另一个文件