Assembly 8086中段寄存器的值是多少?

Assembly 8086中段寄存器的值是多少?,assembly,x86,x86-16,Assembly,X86,X86 16,我刚刚开始阅读有关intel 8086的内容,并对其内存提出了一个问题 我读到地址总线是20位宽的,这意味着地址空间是1MB,并且这个空间被划分为段 问题是: 四段寄存器,CS、DS、SS和ES,是只读的还是我可以设置它们的值,以及它们的默认值 我看到了以下装配教程: ORG 100h MOV AX, 0B800h ; set AX = B800h (VGA memory). MOV DS, AX ; copy value of AX to DS. MOV CL, 'A' ; CL = 41h

我刚刚开始阅读有关intel 8086的内容,并对其内存提出了一个问题

我读到地址总线是20位宽的,这意味着地址空间是1MB,并且这个空间被划分为段

问题是:

  • 四段寄存器,
    CS
    DS
    SS
    ES
    ,是只读的还是我可以设置它们的值,以及它们的默认值

  • 我看到了以下装配教程:

    ORG 100h
    MOV AX, 0B800h ; set AX = B800h (VGA memory).
    MOV DS, AX ; copy value of AX to DS.
    MOV CL, 'A' ; CL = 41h (ASCII code).
    MOV CH, 01011111b ; CL = color attribute.
    MOV BX, 15Eh ; BX = position on screen.
    MOV [BX], CX ; w.[0B800h:015Eh] = CX.
    RET
    
  • 关于第一行,这是否意味着该代码将存在于代码段空间的地址
    0x100
    中,还是存在于整个地址空间中

    这句话:

    MOV [BX], CX
    

    这是否意味着每次我在
    MOV
    指令中引用地址时,应该从数据段的起始地址估算地址?(正如他所写,目标是值+数据段reg中的值)

    获取英特尔8088/86手册。这些都在这里解释过了

    是的,你可以改变它们,你必须能够改变它们,使它们变得有用。默认情况下使用明显的段(代码代表代码,数据代表数据),但也有一些地方可以在数据指令中指定其他段

    org 0x100表示该代码(或遵循org指令的数据)从段内的地址0x100开始

    首先,我不得不指出,您似乎在这里谈论的是8086“实模式”寻址,这是一种非常古老的方式,几乎没有任何用途了。几乎所有现代操作系统都在“受保护模式”下运行,该模式支持许多增强功能(如平面32位和64位内存空间寻址、虚拟内存等),从而极大地改变了所有这些功能的工作方式

    据我所知,现在的大多数操作系统甚至都没有任何方式来运行这样的代码(在真实模式下),因此,如果您对学习汇编语言以编程现代PC机感兴趣,您可能希望找到一些更新的源代码来学习

    话虽如此,假设您确实有理由想这样做(例如使用某些嵌入式处理器),或者只是出于历史目的而好奇:

  • 是的,可以修改8086实模式段寄存器。与修改更通用的寄存器相比,执行此操作的指令和选项更为有限(例如,没有直接将值加载到段寄存器的指令,这就是为什么在您引用的代码中,值首先加载到
    AX
    ,然后
    AX
    加载到
    DS
    ),并且也可以根据您使用的段寄存器而有所不同

    通常,您永远不会希望直接修改
    CS
    (“代码段”)寄存器,因为这会导致立即更改处理器正在运行的代码(可能是以您真正不希望的方式)。修改
    CS
    的常用方法是使用“跳远”或“长呼叫”指令,这将同时更新
    CS
    IP
    (指令指针)。类似地,
    SS
    (“堆栈段”)通常在程序执行开始时设置,并且从未更改过(但从技术上讲,如果您有非常令人信服的理由这样做,它可能会更改)

    DS
    ES
    是通用数据段寄存器,程序通常会更改这些寄存器,但它们希望最好地访问它们想要使用的内存(如上面的示例代码所示)

    至于这些寄存器的初始值,通常在调用程序代码之前由操作系统确定。传统上,在MS-DOS中,有两种编写程序的方法,即.COM文件或.EXE文件。(上面代码中的
    org100h
    行表明它是作为COM程序运行的。)在COM情况下,MS-DOS在调用程序之前会首先将所有段寄存器设置为与
    CS
    相同(也就是说,它们都指向DOS决定在内存中加载程序的位置)。EXE文件格式稍微复杂一些,允许指定一个单独的“数据段”,在这种情况下,操作系统将设置
    DS
    ES
    以在启动程序之前指向该段。在EXE程序中,DOS通常也会为它们设置单独的堆栈段(
    SS

  • ORG 100h行告诉汇编程序“假设以下代码将在地址100h处加载”。在实模式代码中,这样的地址总是相对于
    CS
    (因此,只要
    CS
    设置为正确的值,使代码相对于
    CS
    处于100小时,程序实际上可以加载到内存中的许多位置)

  • 默认情况下,大多数数据操作(如
    MOV
    )的地址都是相对于
    DS
    计算的(对于某些指令,您可以通过显式指定要使用的不同段来更改地址,但是否以及如何执行此操作取决于操作码和使用方式)。但是,有一些指令在默认情况下设计为使用其他段。总之,最好阅读您想要了解的每个操作码的文档,以确定它如何使用哪个段寄存器


  • ... 目标是数据段reg中的值+值。这是不对的。应该是。。。目标是值+数据段reg中的值乘以16。20位地址来自16位偏移量加上左移4位的16位段寄存器。这是一种处理超过2**16字节地址的笨拙方法,理论上没有什么意义,编码上有很多困难,在这一点上,只有微弱的历史意义。更有趣的