我对真实的模式下的段大小有一点怀疑,因为它们不能超过64K,但可以是less than that.
我的问题是这些段的大小和基址是如何初始化的?就像保护模式下的GDT和LDT一样。Real mode segments can also overlapped,disjoint or adjacent.
像BIOS有一些保留区域的具体事情,如 Boot 代码,视频缓冲区等汇编程序需要这样做吗?
我对真实的模式下的段大小有一点怀疑,因为它们不能超过64K,但可以是less than that.
我的问题是这些段的大小和基址是如何初始化的?就像保护模式下的GDT和LDT一样。Real mode segments can also overlapped,disjoint or adjacent.
像BIOS有一些保留区域的具体事情,如 Boot 代码,视频缓冲区等汇编程序需要这样做吗?
2条答案
按热度按时间gmxoilav1#
真实的模式下的段限制为64 K,即使在386或更高版本的CPU上,您也可以通过前缀使用32位地址大小。例如,
mov ax, [edx + ecx*4]
在实模式下的偏移量仍限制为64 KiB。如果超出此限制,则会在286+上引发#GP异常(如果段为SS,则为
#SS
)。8086没有#SS或#GP异常,它没有一般或其他保护,只是使用
Sreg << 4
添加到偏移量以形成线性地址。16-位地址大小可以通过
seg:FFFF
上的一个字或更宽的访问超过64 K段限制。在8086上,较高的字节来自seg:0000
(在计算第二个内存总线事务的新线性地址之前,在逻辑地址中的偏移回绕,而不是访问段的64 K线性范围之外)。在286和更高版本上,在这种情况下,数据和指令都为
#GP
或#SS
。* https://www.os2museum.com/wp/does-eip-wrap-around-in-16-bit-segments/ *一般而言,像
[bx + si + 1]
这样的寻址模式在16位处换行。(而SP=0的push word
会自动换行到SP=FFFEh,只要堆栈对齐就没有问题)。(在386中添加的)可以超过真实的模式中的段限制,除了在段的最末端的字或更宽的访问。在8086上,从最高可能地址的64 K以内开始的段在1 MiB处环绕,如果禁用A20,则在更高的CPU上也是如此。否则,对于
FFFF:FFFF
seg:off =0x10ffef
linear这样的地址,它们会延伸到1 MiB以上。请参阅 * 什么是段以及如何在8086模式下对其进行寻址?*虚幻模式:386真实的模式平面存储器模型
如果您切换到保护模式并设置了段寄存器,CPU会将段描述(基址+限制)保留在内部缓存中,即使切换回16位真实的模式也是如此。这种情况称为**unreal mode**。
在16位模式下写入段寄存器只会将段基址设置为
value << 4
,而不会改变限制,因此非真实模式对于除CS之外的段是比较持久的。CS:EIP是特殊的,特别是当你需要避免在从中断返回时将EIP截断为16位时。push
/pop
/call
/ret
根据当前堆栈段描述符中得B
标志使用SS:ESP
或SS:SP
;地址大小前缀仅影响类似于push word [eax]
与push word [si]
的内容。在真实的模式下向段寄存器写入值时,GDT / LDT被忽略。该值直接用于设置缓存的段基址,而根本不作为选择器。
(Each分段;虚幻模式不是像protected与real那样的实际模式; CPU处于真实的模式。例如,写FS寄存器会将该段恢复到正常的实模式行为,但不会改变其他行为。它只是一个名称,表示处于实模式,缓存的段描述符具有更大的限制,因此您可以使用32位地址大小来获得更大的平面地址空间。通常base=0,limit=4G)
当然,在真实的模式下无法查询段的内部限制值。
lsl
直接从内存中GDT / LDT的描述符中加载段限制值,而不是从内部值中加载(因此这不是您想要的),而且它在实模式下也不可用。有关有意或无意地使片段脱离虚幻模式的更多详细信息,请参见对此答案的注解。
286和386 CPU支持a
LOADALL
instruction,aLOADALL
instruction可以从真实的模式设置段限制,但后来的CPU没有它。评论者说SMM(系统管理模式)可能能够在现代x86上做类似的事情。rryofs0p2#
在真实的模式下,分段地址被硬连接到内存中。要获得物理地址,可以使用以下等式:
段地址和偏移地址都是16位的。通过使用这个等式,你可以制作一个20位的地址,访问低640kB的RAM没有问题。
没有一个表来保存某个段的位置。问题是你必须同时设置段寄存器和偏移寄存器才能访问任何地址。所以你可以通过一个简单的循环访问最多64k的RAM字节,这个循环只是增加偏移寄存器,这使得内存访问更大的缓冲区比在平面模型中更不方便。