; ke_helpers.asm .code ; void KeFlushGdt(GDTR* pGdtr, uint16_t codeSel, uint16_t dataSel, uint16_t tssSel); KeFlushGdt PROC ; RCX = pGdtr (pointer to limit/base struct) ; RDX = codeSel ; R8 = dataSel ; R9 = tssSel ; 1. Load the GDT lgdt fword ptr [rcx] ; 2. Reload Data Segments mov ax, r8w mov ds, ax mov es, ax mov ss, ax mov fs, ax mov gs, ax ; 3. Load Task Register mov ax, r9w ltr ax ; 4. Reload Code Segment (Far Return) ; In MASM64, use OFFSET to get the address of the label. ; We push the selector, then the offset, then issue retff / retfq. push rdx ; Push new Code Selector (RDX) lea rax, [reload_cs] ; RIP-relative address of the label push rax ; Push "return" address db 048h, 0CBh ; rex_w retf (effectively retfq) reload_cs: ret KeFlushGdt ENDP ; void KeFlushIdt(IDTR* pIdtr); KeFlushIdt PROC lidt fword ptr [rcx] ret KeFlushIdt ENDP ; KCPU* KeReadCurrentCpuFromGs(void); ; GS:0 contains KCPU.Self while executing in the kernel. KeReadCurrentCpuFromGs PROC mov rax, qword ptr gs:[0] ret KeReadCurrentCpuFromGs ENDP END