[英]After load the GDT
# Load the GDT.
mov $gdt_descriptor, %ecx
lgdt (%ecx)
mov $0x10, %cx
mov %cx, %ds
mov %cx, %es
mov %cx, %fs
mov %cx, %gs
mov %cx, %ss
ljmp $0x8, $1f
1: mov $kernel_stack, %esp
I am unable to understand what this code does. 我无法理解这段代码的作用。 Why mov $0x10 to cx and then subsequently to other registers after loading GDT?
为什么在加载GDT后将mov $ 0x10转换为cx然后再转到其他寄存器? And what does ljmp instruction do?
ljmp指令有什么作用?
It loads the segment descriptor caches (inside the CPU) from the new GDT which the lgdt
told the CPU about. 它从
lgdt
告诉CPU的新GDT加载段描述符缓存(在CPU内部)。
The segment descriptions inside the CPU don't update automatically when you change table entries, or change where the table points. 更改表条目或更改表指向的位置时,CPU内部的段描述不会自动更新。
You can even switch back to real mode with DS base=0 limit=4GiB (and same for ES and SS), and use 32-bit addresses in real mode until the next mov ds, r16
or pop ds
instruction overwrites the cached segment description. 您甚至可以切换回实模式,DS base = 0 limit = 4GiB(ES和SS相同),并在实模式下使用32位地址,直到下一个
mov ds, r16
或pop ds
指令覆盖缓存的段描述。 (This is called big / huge unreal mode , huge if you do it for CS as well, but that's less convenient because interrupts in real mode only save IP, not EIP.) (这被称为大/巨大的虚幻模式 ,如果你也为CS做了很大,但这不太方便,因为实模式中的中断只保存IP,而不是EIP。)
ljmp
is a far jmp
, which sets CS (in this case to use a different descriptor than the data descriptors). ljmp
是一个far jmp
,它设置CS(在这种情况下使用与数据描述符不同的描述符)。 x86 doesn't allow mov
or pop
to set CS, only far jump. x86不允许
mov
或pop
设置CS,只能远程跳转。 Presumably the CPU isn't changing modes with this jump, otherwise the asm source would need to use a .code32
or .code16
directive. 据推测,CPU不会通过此跳转来更改模式,否则asm源需要使用
.code32
或.code16
指令。
The target is the 1:
label, in the f
orward direction. 目标是
1:
标签,在f
方向。 So the mov
to %esp
is decoded/run with whatever code-segment settings were in GDT index 1. (The low 3 bits of segment selectors are permission bits, so $8
is GDT index 1, and $0x10
is GDT index 2.) 所以使用GDT索引1中的任何代码段设置解码/运行
mov
to %esp
。(段选择器的低3位是权限位,因此$8
是GDT索引1, $0x10
是GDT索引2。)
It's a bit weird to separate the mov
to %ss
from the instruction that sets %esp
, because x86 automatically defers interrupts until the instruction after a mov
to SS
. 这是一个有点怪异的分离
mov
到%ss
从设置指令%esp
因为86会自动推迟中断,直到之后的指令mov
到SS
。 This lets you atomically set SS:SP without using cli
/ sti
, but probably this code runs with interrupts disabled already. 这允许您在不使用
cli
/ sti
情况下以原子方式设置SS:SP,但可能此代码在已禁用中断的情况下运行。 This code probably only runs once during bootup, so it makes sense to just disable interrupts for as long as necessary to set up a new GDT and IDT. 此代码可能仅在启动期间运行一次,因此只需在设置新GDT和IDT所需的时间内禁用中断即可。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.