Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/40.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Operating system 为什么我们需要;输入“;还是32位保护模式?_Operating System_Cpu_Cpu Architecture_Cpu Registers - Fatal编程技术网

Operating system 为什么我们需要;输入“;还是32位保护模式?

Operating system 为什么我们需要;输入“;还是32位保护模式?,operating-system,cpu,cpu-architecture,cpu-registers,Operating System,Cpu,Cpu Architecture,Cpu Registers,最近我对从头开始构建一个小型玩具操作系统很感兴趣,现在我真的很困惑。请你帮帮我好吗 问题 我一直在想,为什么我们还要费心进入32位保护模式呢 我的意思是,为什么不将旧指令从16位改写为32位(或64位),这样我们就可以直接编码(例如,直接访问更多内存地址)。。。这个转换过程的意义是什么…为什么 我感到困惑的原因是,我正在阅读的教程首先教我如何使用16位(一些基本BIOS指令)启动,而它声称“32位更好”,我完全同意这一点,因此我们必须进入32位保护模式。在我看来,这只是位长度的简单扩展?为什么如

最近我对从头开始构建一个小型玩具操作系统很感兴趣,现在我真的很困惑。请你帮帮我好吗

问题 我一直在想,为什么我们还要费心进入32位保护模式呢

我的意思是,为什么不将旧指令从16位改写为32位(或64位),这样我们就可以直接编码(例如,直接访问更多内存地址)。。。这个转换过程的意义是什么…为什么


我感到困惑的原因是,我正在阅读的教程首先教我如何使用16位(一些基本BIOS指令)启动,而它声称“32位更好”,我完全同意这一点,因此我们必须进入32位保护模式。在我看来,这只是位长度的简单扩展?为什么如此不同(难以使用BIOS、GDT、电子寄存器……?

英特尔一直试图保持其CPU向后兼容(现在仍然如此)。
一种新型的、别致的、不能运行任何现有软件的CPU对业界来说是一块坚不可摧的石头

操作码
b8
mov-ax,imm16
,在不破坏兼容性的情况下,没有其他可能的解释方法,包括
mov-eax,imm32

除非您在某个地方设置了一个标志,让CPU知道这样做是可以的。
这是切换,现在
b8
mov-eax,imm32

因此,旧指令在某种意义上被“覆盖”

英特尔本可以使用全新的操作码,但这将是对操作码的巨大浪费(当时操作码空间已经非常拥挤),再加上沿着这条路走下去并避免显式切换,CPU必须同时处于实模式和保护模式(因为它不能放弃对16位代码的支持)。
这是一个非常混乱的设计要求,或在最好的噩梦

如果不是因为处理中断(可能是CPU执行自动操作的任何机制)的问题,可以使用前缀

受保护模式伴随着一种新的保护方案出现,这是公认的过度设计,但我们需要处理它,它的GDT、IDT、TSS等等。
这种机制是在x86体系结构上出现32位计算之前设置的,也就是说,当286中没有32位寄存器/地址时,它就出现了。
当英特尔意识到需要32位计算时,它抓住机会将其与改进版的保护方案一起发布

每当CPU和软件之间签订新合同时,通常都要求软件有明确的意图,这可防止任何虚假激活

因此,交换提供:

  • 更简单的设计
  • 操作码的重用(避免使用前缀)
  • 证明软件是为理解新合同而编写的证明
  • 对于不理解新合同的软件,使用相同的环境
随着UEFI的出现,一些限制已被放宽,UEFI引导加载程序(或任何应用程序或驱动程序)以64位模式引导(如果CPU太旧,无法使用64位模式,则为32位)。
如果您对旧版BIOS引导不满意,可以尝试UEFI。
请注意,64位模式依赖于它之前的所有内容,包括保护模式和PAE分页。

你可以把它们藏在地毯下一段时间,但如果你计划继续编写操作系统,掌握基本知识会有回报的

16位模式和32位模式之间存在许多差异。而且,在引入32位时,为了向后兼容,需要先引导到16位模式,然后切换到32位模式。依我看,在现有操作系统的用户空间中,asm有很多好东西需要学习/做。一旦您熟悉了这一点,学习操作系统开发方面的知识就容易多了:您可以阅读并理解任何示例正在做什么,您只需要阅读为什么,而不必费解说明的机制。在这种情况下,如果您知道x86指令的机器编码是如何工作的,答案是显而易见的:根据模式,有一个默认的操作数大小,操作数大小前缀
0x66
翻转将其设置为非默认大小(32位或64位模式下为16位),这可能会在英特尔CPU()上的预解码阶段导致长度更改前缀暂停,如果没有前缀的指令将有一个imm32,但有前缀的指令只有一个imm16,因此更短。(或对于16位寻址模式,disp32与disp16。)无论如何,显然出于代码大小的原因,您不希望几乎所有指令都需要
0x66
前缀,就像唯一可用的默认操作数大小为16位时一样。尤其是在386设计时,代码大小比现在更为重要。简单的方法是仍然使用16位作为默认操作数/地址大小,并依靠前缀设置32位操作数大小。我认为每个32位操作数大小/地址大小指令都可以在16位模式下使用前缀进行编码(VEX前缀除外,如果x86真的以这种方式工作,VEX前缀的设计会有所不同)。这对于代码大小来说显然是可怕的,因为几乎每一条指令都需要一个
0x66
操作数大小前缀,而且许多指令还需要地址大小。但由于您仍然绝对需要一种新的中断模式来推送32位EFLAGS/EIP,如果不执行与当前设计类似的操作并更改默认操作数大小,那将是愚蠢的。这是否正确“UEFI引导加载程序在64位模式下引导”?我的印象是,在前几条指令中,它们切换到64位模式。