2011-04-26 152 views
13

没错。我今天花了三个多小时试图了解为什么在保护模式下不能调用BIOS的ISR。我得到的,一旦你设置和IDT它不会一定是在平时的地址IVT加段不必须在保护模式下,等固定的大小。但我还是不明白为什么你不能仅仅指刚创建单条4GB段,将您的IDT段映射到BIOS IVT,将所有内容设置为响铃0并调用它们。不应该那样工作?为什么我不能从保护模式调用BIOS中断?

大多数文章要么说:“记住,你不能使用BIOS在保护模式下的中断!”没有探讨这个问题,或者是非常具有描述性的,并且引用陷阱,例外,图片重塑,缺乏权利以及段登记的问题作为其背后的原因。

这将是非常有益的,如果有人能拿出一个更人性化的解释......我不怀疑什么文章说,我只是想知道为什么它是这样一个“痛苦”!

在此先感谢!

回答

9

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

+0

非常感谢您的意见! – Max 2011-05-26 14:33:24

3

我到达回到旧的东西,所以这可能是稍微偏离,而是“保护”模式的主要目的之一是从应用程序代码隔离敏感/安全代码。原来的规范有4级0到3环。实践中,我只见过操作系统的环0和应用程序的环3。允许应用程序修改或调用中断可能会让他们进入操作系统。所以这样的操作仅适用于在环0中运行的代码 - 即操作系统。让代码在ring 0中运行的唯一方法是创建一个驱动程序。 Windows将基本加载驱动程序到它自己的专用内核内存(虽然这样也有/正在改变在Windows Vista/7)环运行0

+1

谢谢保罗。但是在这种情况下,创建一个在ring 0中运行的设备驱动程序是不可能的,它只需调用相应的BIOS ISR,然后将适当的值返回给应用程序? – Max 2011-04-26 19:01:07

6

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

此外,任何段寄存器加载(除零之外)将表现不同在比它在任何保护模式实模式。同样,实模式代码和保护模式的代码能够共同努力,使之可以编写代码工作,但它是很不容易的。

例如,`

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` 

应该工作一样好。

相关问题