14

对。我今天花了三个多小时试图理解为什么在保护模式下不能调用 bios ISR。我明白了,一旦你设置了 IDT,它就不一定在 IVT 的常用地址中,加上段在保护模式下没有固定大小等。但我仍然不明白你为什么不能创建一个 4GB段,将您的 IDT 段映射到 BIOS IVT,设置环 0 中的所有内容并调用它们。那不应该工作吗?

大多数文章要么说:“记住你不能在保护模式下使用 BIOS 中断!” 没有探索该主题或具有极强的描述性,并引用陷阱、异常、图片重映射、缺乏权利和段寄存器问题作为其背后的原因。

如果有人能提出更人性化的解释,那将非常有帮助……我并不怀疑文章所说的,我只是想了解为什么它如此“痛苦”!

提前致谢!

4

3 回答 3

10

我认为最大的问题是 BIOS 例程是在假设处理器处于实模式时编写的。如果从不受支持的上下文中调用它们,则无法确定 BIOS 例程会按预期运行。它们可能会自行失败,也可能会弄乱处理器状态并将您踢出保护模式。

于 2011-05-03T16:54:15.103 回答
6

Max,如果操作系统在 16 位保护模式下运行,您可能会创建在 ring 0 中运行的设备驱动程序,该驱动程序调用更简单的 BIOS ISR。但在 32 位模式下,第一个 16 位或 32 位地址偏移或立即值将被错误解释,指令流将不同步。在实数或 16 位保护模式下,立即数和偏移值默认为 16 位长,在 32 位保护模式下,它们为 32 位长,在 64 位(长)模式下,它们为 32 位或 64 位长。因此,只能在 ISR 中使用表示为字节的偏移量(< 128,如果我没记错的话)和字节立即值。

此外,任何段寄存器加载(非零)在实模式下的行为与在任何保护模式下的行为不同。同样,实模式代码和保护模式代码可以一起工作,以使编写有效的代码成为可能,但这并不容易。

例如,`

  mov ah, 0B8h  
  mov al, 000h  
  mov es, ax  
  mov byte ptr es:0, 'o'  
  mov byte ptr es:2, 'k'`

将在实模式下将字母“ok”放在文本模式屏幕的左上角,但要使其在 16 位或 32 位保护模式下工作,偏移量 0xB800 处的全局描述符表条目必须有一个基础地址为 0x000B8000。

但是,如果您对仅在 16 位保护模式下运行感到满意,那么更常见的代码:`

  mov ax, 0B800h   
  mov es, ax  
  mov dword ptr es:0, 0076b076fh`  

应该也能正常工作。

于 2011-05-16T15:24:55.907 回答
3

我回到旧的东西,所以这可能会稍微偏离,但“保护”模式的主要目的之一是将敏感/安全代码与应用程序代码隔离开来。最初的规范有 4 个级别,从环 0 到环 3。在实践中,我只见过用于操作系统的环 0 和用于应用程序的环 3。允许应用程序修改或调用中断可能会为它们提供进入操作系统的后门。因此,此类操作仅适用于在环 0 中运行的代码 - 即操作系统。让代码在 ring 0 中运行的唯一方法是创建驱动程序。Windows 基本上会将驱动程序加载到它自己的私有内核内存中(尽管这在 Windows Vista/7 中已经/正在改变)在环 0 中运行。

于 2011-04-26T18:52:42.213 回答