简体   繁体   English

加载GDT后

[英]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, r16pop 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不允许movpop设置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会自动推迟中断,直到之后的指令movSS 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM