OS专题-了解16位实模式下的内存编制

OS专题-了解16位实模式下的内存编制

之前在了解CPU中已经介绍过16位实模式,现在我们就来进一步了解一下在16位实模式中是如何进行内存编制管理的。

这里首先要了解16位的意思,就是在处理时只能处理16位的数据,也正是因为如此,高位数的CPU在这个阶段也要按照16位的标准去处理数据。可以想想16位的数据很有局限性,因为取值范围要小于32位和64位。而我们的内存空间确实非常的大。那这么小的16位如何存储大量的内存地址呢?为了解决这个问题,引入了一个新的概念:段寻址

TMD,又是一个计算机组成原理,有没有后悔没好好学?

段寻址,就是将整个1M空间以64K划分为若干段,例如一个20位的地址,因此有2^20=1M存储空间的直接寻址能力。在寻址一个内存具体单元时,由一个基址再加上某些寄存器提供的16位偏移量来形成实际的20位物理地址。这个基址就是CPU中的段寄存器。在形成20位物理地址时,段寄存器的16位的数会自动左移4位,然后与16位偏移量相加,即可形成所需的内存地址。在实模式下,我们使用A:B形式的逻辑地址来寻址内存。用公式表示就是:

$$
物理地址 = (A * 0x10) + B
$$
OR
$$
物理地址 = (A << 4) + B
$$

纯实模式中的寄存器被限制为 16 位用于寻址。16 位可以表示 0 到 64k 之间的任何整数。这意味着如果我们将 A 设置为固定值并允许 B 更改,我们可以寻址 64k 的内存区域。这个 64k 的区域称为一个段。

x86系列计算机有6个段寄存器(CS, DS, ES, FS, GS, SS)。它们是完全独立的。
这些寄存器被处理器隐式的使用,因此你如果设置了这些寄存器。比如你设置了DS那么以后所有的数据地址都会以DS中的值为偏移基址。

我们来根据代码分析吧,请看如下例子:

mov ah, 0x0e

mov al, [the_secret]
int 0x10 ; 现在我们用原来的打印方式看看是否可以输出

mov bx, 0x7c0 ; 我们给段赋值,对于段而言他是自动进行 `<< 4`计算的
mov ds, bx
; 注意: 从现在开始所有的地址都会隐式的使用`ds`段地址
mov al, [the_secret]
int 0x10

mov al, [es:the_secret]
int 0x10 ; 看看显示引用`es`会怎么样

mov bx, 0x7c0
mov es, bx
mov al, [es:the_secret]
int 0x10 ; 现在显示正常了


jmp $

the_secret:
    db "X"

times 510 - ($-$$) db 0
dw 0xaa55

OS专题-了解16位实模式下的内存编制
https://blog.cikaros.top/doc/26508ea8.html
作者
Cikaros
发布于
2022年9月23日
许可协议