lgdt
它从告诉 CPU的新 GDT 加载段描述符缓存(在 CPU 内部) 。
当您更改表条目或更改表指向的位置时,CPU 内的段描述不会自动更新。
您甚至可以使用 DS base=0 limit=4GiB 切换回实模式(ES 和 SS 相同),并在实模式下使用 32 位地址,直到下一条mov ds, r16
或pop ds
指令覆盖缓存的段描述。(这被称为big / huge unreal mode,如果你也为 CS 这样做,那么它是巨大的,但这不太方便,因为实模式下的中断只保存 IP,而不是 EIP。)
ljmp
是 a far jmp
,它设置 CS(在这种情况下使用与数据描述符不同的描述符)。x86 不允许mov
或pop
设置 CS,只能跳远。推测 CPU 不会通过此跳转更改模式,否则 asm 源将需要使用.code32
or.code16
指令。
目标是1:
标签,在f
正向。因此,mov
to%esp
使用 GDT 索引 1 中的任何代码段设置进行解码/运行。(段选择器的低 3 位是权限位,$8
GDT 索引 1 和$0x10
GDT 索引 2 也是如此。)
mov
将to%ss
与设置的指令分开%esp
有点奇怪,因为 x86 会自动将中断推迟到to之后的指令。这使您可以在不使用/的情况下自动设置 SS:SP ,但可能此代码在已禁用中断的情况下运行。这段代码可能只在启动期间运行一次,因此只要设置新的 GDT 和 IDT 就需要禁用中断是有意义的。mov
SS
cli
sti