gpt4 book ai didi

assembly - 引导加载程序中 gdt 的远跳转

转载 作者:行者123 更新时间:2023-12-02 10:35:37 25 4
gpt4 key购买 nike

flush_gdt:
lgdt [gdtr]
jmp 0x08:complete_flush

complete_flush:
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
ret

我无法理解这段代码的作用。 flush_gdt 是一个标签 OK ,然后 lgdt [gdtr]gdtr 寄存器中加载 48 位 指针来自 jmp 0x08:complet_flush

jmp指令的作用是什么?那么为什么我们要将 0x10 移动到 ax,然后再移动到其他寄存器

最佳答案

x86 支持两种虚拟内存方案 ( read about it here ):

  • 分段必须使用段表 GDT 进行管理。
  • 分页,可选,使用页表 PDT 进行管理。

大多数操作系统想要使用分页并且不希望分段,但是它必须而且不能仅仅被禁用。

所以技巧是禁用它的效果,因为它不存在。这通常可以通过创建 4 个大的重叠段描述符(在空段旁边)来完成:

  • 段索引 0:空段描述符
  • 段索引 1:特权(内核)模式的代码段描述符
  • 段索引2:特权(内核)模式的数据段描述符
  • 段索引3:非特权(用户)模式的代码段描述符
  • 段索引4:非特权(用户)模式的数据段描述符

所有这些段从0x00000000开始到0xffffffff,因此最终会得到重叠的大段,其中包含特权代码和数据,以及非特权代码和数据同一时间。这应该打开虚拟内存并禁用分段效果。

处理器使用段选择器(段寄存器csdsss ...)来找出正确的段(一旦再次强调,分割是必须的)。

每个段选择器都是 16 位大小,并具有以下布局 ( source ):

enter image description here

  • 前两位表示权限级别,x86支持4个级别,但实际使用的只有其中两个(00最高,11最低)。

  • 第三位指示应使用的表,主要是 0,即 GDT。

  • 其余 13 位表示段索引。

如果您解释在 cs 中加载的 0x08,它将是二进制文件:

0000000000001     0         00
index 1 (code) GDT privileged

以及在dsss、...中加载的0x10:

0000000000010     0         00
index 2 (data) GDT privileged

如果您阅读任何用户模式程序的段选择器,您应该会看到 cs 值为 27 (0x1b),这意味着:

0000000000011     0         11
index 3 (code) GDT non-privileged

数据选择器dsss、...应存储35 (0x23):

0000000000100     0         11
index 4 (data) GDT non-privileged

数据段选择器(寄存器)可以使用简单的 mov 指令轻松修改,但 cs 不能与 mov 一起使用>,因此您使用 jmp 0x08:OFFSET 将段配置加载到代码段选择器中。

关于assembly - 引导加载程序中 gdt 的远跳转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23978486/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com