Я не уверен, почему перемещение mov gs,ax
вызвало бы немедленную тройную ошибку Windows, но вскоре произойдет сбой. В 64-битном ядре Windows сегмент GS используется в качестве указателя для доступа к текущему процессору Область управления процессором (PCR). Каждый ЦП имеет свое базовое значение GS, указывающее на свою PCR Ваша последовательность mov ax,gs
mov gs,ax
фактически нарушает это, потому что загружает неверное значение для базы GS в кэш дескриптора.
GDT на самом деле не содержит правильную базу для регистра GS. Поскольку GDT может хранить только 32-битные адреса, он фактически не используется для загрузки базы GS. Вместо этого используются MSR IA32_GS_BASE и IA32_KERNEL_GS_BASE, последние в сочетании с инструкцией SWAPGS, для установки 64-битного базового адреса для сегмента GS. Значение селектора, хранящееся в регистре GS, является просто фиктивным значением.
Таким образом, ваша инструкция mov gs,ax
загружает фиктивное 32-битное базовое значение, хранящееся в GDT, а не 64-битное значение, хранящееся в IA32_GS_BASE. Это означает, что базовый адрес сегмента GS установлен на 0, а не на адрес PCR для текущего CPU. После загрузки этой некорректной базы GS это лишь вопрос времени, когда ядро Windows попытается использовать регистр GS для доступа к PCR (с инструкцией, подобной mov rax, gs:[10]
) и в конечном итоге прочитает, что, вероятно, не отображено в памяти, вызывая неожиданную ошибку страницы ядра. и сбой.