8086中段寄存器的值是多少? [英] What is the value of segment registers in 8086?

查看:45
本文介绍了8086中段寄存器的值是多少?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始阅读有关 intel 8086 的文章,并对其内存有疑问.

I have just started to read about intel 8086 and have a question concerning its memory.

我读到地址总线是20位宽的,也就是说地址空间是1MB,这个空间被分成了段.

I read that the address bus is 20-bit wide, which means the address space is 1MB, and this space is divided into segments.

问题是:

  1. 四个段寄存器,CSDSSSES,是否读取only 或者我可以设置它们的值,它们的默认值是什么?

  1. the four segment registers, CS, DS, SS and ES, are they read only or I can set their values, and which are their default values?

我看到了以下组装教程:

I saw the following assembly tutorial:

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中,还是存在于整个地址空间中

Concerning the first line, does that mean this code will exist in address 0x100 in code segment space or in the whole address space

和线:

MOV [BX], CX

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

Does that mean every time I reference an address in the MOV instruction, the address should be estimated from the start address of the data segment? (as he wrote that the destination is the value + the value in the data segment reg)

推荐答案

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

据我所知,现在大多数操作系统甚至没有办法运行这样的代码(在实模式下),所以如果你有兴趣为了编程而学习汇编现代 PC,您可能想找到一些最近的资源来学习.

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

That having been said, assuming you do have some reason to want to do this (such as working with certain embedded processors), or are just curious for historical purposes:

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

  1. Yes, the 8086 real-mode segment registers can be modified. The instructions and options for doing this are a bit more limited than modifying the more general-purpose registers (for example, there's no instruction to just load a value directly into a segment register, which is why in the code you quoted, the value is first loaded into AX, and then AX is loaded into DS), and can also vary depending on which segment register you're working with.

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

In general, you would never want to modify CS (the "code segment") register directly, as that would result in immediately changing what code the processor is running (probably in a way you really don't want). The usual way to modify CS is with a "long jump" or "long call" instruction, which will update both CS and IP (the instruction pointer) at the same time. Likewise, SS (the "stack segment") is usually set at the beginning of program execution and never changed (but it technically could be if you had some really compelling reason to do so).

DSES 是通用数据段寄存器,程序更改它们是很常见的,但是他们想最好地访问他们想要使用的内存(如上面的示例代码所示).

DS and ES are general-purpose data segment registers and it was fairly common for programs to change these however they wanted to best access the memory they wanted to work with (as your example code above demonstrates).

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

As for the initial values for these registers, those were typically determined by the operating system prior to calling the program's code. Traditionally, in MS-DOS, there were two ways to write programs, as .COM files or as .EXE files. (The ORG 100h line in the code above suggests that it was intended to be run as a COM program.) In the COM case, MS-DOS would initially set all of the segment registers to be the same as CS (that is, they'd all point to wherever DOS had decided to load the program in memory) before invoking the program. The EXE file format was somewhat more sophisticated, and allowed specifying a separate "data segment", in which case the OS would set DS and ES to point to that segment before starting the program instead. In EXE programs, DOS would also typically set up a separate stack segment (SS) for them as well.

ORG 100h 行告诉汇编器假设以下代码将在地址 100h 加载".在实模式代码中,像这样的地址总是相对于 CS(所以程序实际上可以被加载到内存中的很多地方,只要 CS 被设置为使代码相对于 CS 为 100h 的正确值).

The ORG 100h line tells the assembler "assume that the following code will be loaded at address 100h". In real-mode code, addresses such as this are always relative to CS (so the program could actually be loaded many places in memory, as long as CS is set to the correct value to make the code be at 100h relative to CS).

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

Most addresses for data operations (such as MOV) will be calculated relative to DS by default (for some instructions, you can change that by explicitly specifying a different segment to use, but whether and how you can do that depends on the opcode and the way you're using it). There are, however, a few instructions which are designed to use other segments by default. In summary, it's really best to read the docs for each opcode you want to know about to determine how it uses which segment registers.

这篇关于8086中段寄存器的值是多少?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆