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

标签 assembly x86 x86-16

我刚刚开始阅读有关Intel 8086的文章,并对它的内存有疑问。

我读到地址总线为20位宽,这意味着地址空间为1MB,并且该空间分为多个段。

问题是:


这四个段寄存器CSDSSSES是只读的,还是我可以设置它们的值,它们的默认值是什么?
我看到了以下汇编教程:

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中的值)

最佳答案

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

据我所知,当今大多数操作系统甚至都不再具有以这种方式(以实模式运行)的代码,因此,如果您有兴趣学习用于对现代PC进行编程的汇编语言,则可能需要寻找更多最新资源以供学习。

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


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

通常,您永远都不想直接修改CS(“代码段”)寄存器,因为这将导致立即更改处理器正在运行的代码(可能以您确实不想要的方式)。修改CS的通常方法是使用“跳远”或“长调用”指令,这将同时更新CSIP(指令指针)。同样,SS(“堆栈段”)通常在程序执行开始时设置,并且从不更改(但从技术上讲,如果您有某些确实令人信服的理由这样做,则可以这样)。

DSES是通用数据段寄存器,程序更改它们非常普遍,但是它们希望最好地访问要使用的内存(如上面的示例代码所示)。

至于这些寄存器的初始值,通常是由操作系统在调用程序代码之前确定的。传统上,在MS-DOS中,有两种方法可以编写程序:.COM文件或.EXE文件。 (上面代码中的ORG 100h行表明它打算作为COM程序运行。)在COM情况下,MS-DOS最初会将所有段寄存器设置为与CS相同(即是,它们都指向DOS在调用程序之前决定将程序加载到内存中的任何位置。 EXE文件格式稍微复杂一些,允许指定一个单独的“数据段”,在这种情况下,操作系统将在启动程序之前将DSES设置为指向该段。在EXE程序中,DOS通常也会为它们设置一个单独的堆栈段(SS)。
The ORG 100h行告诉汇编器“假定以下代码将在地址100h处加载”。在实模式代码中,此类地址始终相对于CS(因此,只要将CS设置为正确的值以使代码相对于100h,该程序实际上就可以加载到内存中的许多位置。到CS)。
默认情况下,大多数数据操作地址(例如MOV)将相对于DS计算(对于某些说明,您可以通过显式指定要使用的其他段来更改地址,但是是否以及如何执行此操作取决于操作码以及您的使用方式)。但是,有一些指令默认情况下旨在使用其他段。总而言之,最好阅读您想了解的每个操作码的文档,以确定它如何使用哪个段寄存器。

关于assembly - 8086中段寄存器的值是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18837627/

相关文章:

assembly - MUL 在不应该设置 OF 时设置了 OF

assembly - 如何在 16 位汇编程序中传递/检索 DOS 命令行参数?

c - 关于linux内核__asm__语法

c - 汇编函数不会更改从 c 发送的数组中的值

assembly - pdp-11 打印机

从 c 调用汇编函数

assembly - 'h' 后缀是什么意思?

debugging - 在 OllyDbg 中,您如何强制/提示在某个位置进行反汇编?

c - 在 MIPS 编程中使用递归调用查找数字的阶乘

assembly - 使用按位运算仅反转二进制数的 MSB