После загрузки 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

Я не могу понять, что делает этот код. Зачем перемещать $0x10 в cx, а затем в другие регистры после загрузки GDT? А что делает инструкция ljmp?

1 ответ

Он загружает кэши дескрипторов сегментов (внутри ЦП) из нового GDT, который lgdt рассказал о процессоре.

Описания сегментов внутри ЦП не обновляются автоматически, когда вы изменяете записи таблицы или меняете точку таблицы.

Вы даже можете переключиться обратно в реальный режим с DS base=0 limit=4GiB (и то же самое для ES и SS), и использовать 32-битные адреса в реальном режиме до следующего mov ds, r16 или же pop ds Инструкция перезаписывает описание кэшированного сегмента. (Это называется большой / огромный нереальный режим, огромный, если вы делаете это также для CS, но это менее удобно, потому что прерывания в реальном режиме сохраняют только IP, а не EIP.)

ljmp это far jmp, который устанавливает CS (в этом случае использовать дескриптор, отличный от дескрипторов данных). х86 не позволяет mov или же pop установить CS, только дальний прыжок. Предположительно, процессор не меняет режимы с помощью этого перехода, в противном случае источник asm должен будет использовать .code32 или же .code16 директивы.

Целью является 1: ярлык, в f в обратном направлении. Итак mov в %esp декодируется / запускается с любыми настройками сегмента кода, которые были в индексе GDT 1. (Младшие 3 бита селекторов сегмента являются битами разрешения, поэтому $8 является индексом GDT 1, и $0x10 является индексом GDT 2.)

Это немного странно отделять mov в %ss из инструкции, которая устанавливает %esp потому что x86 автоматически откладывает прерывания до инструкции после mov в SS, Это позволяет вам настроить SS:SP без использования cli / sti, но, вероятно, этот код выполняется с уже отключенными прерываниями. Этот код, вероятно, запускается только один раз во время загрузки, поэтому имеет смысл просто отключать прерывания на столько времени, сколько необходимо для установки новых GDT и IDT.

Другие вопросы по тегам