; in IA32_REGS structure. This facilitates wrapper function to extract them\r
; into that structure.\r
;\r
+BITS 16\r
push ss\r
push cs\r
- DB 66h\r
- call .Base ; push eip\r
+o32 call dword .Base ; push eip\r
.Base:\r
- pushfw ; pushfd actually\r
+ pushfd\r
cli ; disable interrupts\r
push gs\r
push fs\r
push es\r
push ds\r
- pushaw ; pushad actually\r
+ pushad\r
DB 66h, 0bah ; mov edx, imm32\r
.ThunkAttr: dd 0\r
test dl, THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15\r
jz .1\r
- mov eax, 15cd2401h ; mov ax, 2401h & int 15h\r
+ mov ax, 2401h\r
+ int 15h\r
cli ; disable interrupts\r
jnc .2\r
.1:\r
or al, 2\r
out 92h, al ; deactivate A20M#\r
.2:\r
- xor ax, ax ; xor eax, eax\r
- mov eax, ss ; mov ax, ss\r
- DB 67h\r
- lea bp, [esp + IA32_REGS.size]\r
- ;\r
- ; esi's in the following 2 instructions are indeed bp in 16-bit code. Fact\r
- ; is "esi" in 32-bit addressing mode has the same encoding of "bp" in 16-\r
- ; bit addressing mode.\r
- ;\r
- mov [esi - IA32_REGS.size + IA32_REGS._ESP], bp\r
- mov ebx, [esi - IA32_REGS.size + IA32_REGS._EIP]\r
- shl ax, 4 ; shl eax, 4\r
- add bp, ax ; add ebp, eax\r
+ xor eax, eax\r
+ mov ax, ss\r
+ lea ebp, [esp + IA32_REGS.size]\r
+ mov [bp - IA32_REGS.size + IA32_REGS._ESP], ebp\r
+ mov bx, [bp - IA32_REGS.size + IA32_REGS._EIP]\r
+ shl eax, 4 ; shl eax, 4\r
+ add ebp, eax ; add ebp, eax\r
DB 66h, 0b8h ; mov eax, imm32\r
.SavedCr4: DD 0\r
mov cr4, eax\r
- DB 66h\r
- lgdt [cs:edi + (SavedGdt - .Base)]\r
+o32 lgdt [cs:bx + (SavedGdt - .Base)]\r
DB 66h, 0b8h ; mov eax, imm32\r
.SavedCr0: DD 0\r
mov cr0, eax\r
mov ss, eax\r
DB 66h, 0bch ; mov esp, imm32\r
.SavedEsp DD 0\r
- DB 66h\r
- retf ; return to protected mode\r
+o32 retf ; return to protected mode\r
\r
_EntryPoint:\r
DD _ToUserCode - ASM_PFX(m16Start)\r
; It will be shadowed to somewhere in memory below 1MB.\r
;------------------------------------------------------------------------------\r
_ToUserCode:\r
- mov edx, ss\r
- mov ss, ecx ; set new segment selectors\r
- mov ds, ecx\r
- mov es, ecx\r
- mov fs, ecx\r
- mov gs, ecx\r
+BITS 16\r
+ mov dx, ss\r
+ mov ss, cx ; set new segment selectors\r
+ mov ds, cx\r
+ mov es, cx\r
+ mov fs, cx\r
+ mov gs, cx\r
mov cr0, eax ; real mode starts at next instruction\r
; which (per SDM) *must* be a far JMP.\r
DB 0eah\r
.RealAddr: DW 0, 0\r
\r
mov cr4, ebp\r
- mov ss, esi ; set up 16-bit stack segment\r
- xchg sp, bx ; set up 16-bit stack pointer\r
-\r
-; mov bp, [esp + sizeof(IA32_REGS)\r
- DB 67h\r
- mov ebp, [esp + IA32_REGS.size] ; BackFromUserCode address from stack\r
-\r
-; mov cs:[bp + (_BackFromUserCode.SavedSs - _BackFromUserCode)], dx\r
- mov [cs:esi + (_BackFromUserCode.SavedSs - _BackFromUserCode)], edx\r
+ mov ss, si ; set up 16-bit stack segment\r
+ xchg esp, ebx ; set up 16-bit stack pointer\r
+ mov bp, [esp + IA32_REGS.size]\r
+ mov [cs:bp + (_BackFromUserCode.SavedSs - _BackFromUserCode)], dx\r
+ mov [cs:bp + (_BackFromUserCode.SavedEsp - _BackFromUserCode)], ebx\r
+ lidt [cs:bp + (_16Idtr - _BackFromUserCode)]\r
\r
-; mov cs:[bp + (_BackFromUserCode.SavedEsp - _BackFromUserCode)], ebx\r
- DB 2eh, 66h, 89h, 9eh\r
- DW _BackFromUserCode.SavedEsp - _BackFromUserCode\r
-\r
-; lidt cs:[bp + (_16Idtr - _BackFromUserCode)]\r
- DB 2eh, 66h, 0fh, 01h, 9eh\r
- DW _16Idtr - _BackFromUserCode\r
-\r
- popaw ; popad actually\r
+ popad\r
pop ds\r
pop es\r
pop fs\r
pop gs\r
- popfw ; popfd\r
+ popfd\r
\r
- DB 66h ; Use 32-bit addressing for "retf" below\r
- retf ; transfer control to user code\r
+o32 retf ; transfer control to user code\r
\r
ALIGN 16\r
_NullSegDesc DQ 0\r
;------------------------------------------------------------------------------\r
global ASM_PFX(InternalAsmThunk16)\r
ASM_PFX(InternalAsmThunk16):\r
+BITS 32\r
push ebp\r
push ebx\r
push esi\r
; in IA32_REGS structure. This facilitates wrapper function to extract them\r
; into that structure.\r
;\r
- ; Some instructions for manipulation of segment registers have to be written\r
- ; in opcode since 64-bit MASM prevents accesses to those registers.\r
- ;\r
- DB 16h ; push ss\r
- DB 0eh ; push cs\r
- DB 66h\r
- call .Base ; push eip\r
+BITS 16\r
+ push ss\r
+ push cs\r
+o32 call dword .Base ; push eip\r
.Base:\r
- DB 66h\r
- push 0 ; reserved high order 32 bits of EFlags\r
- pushfw ; pushfd actually\r
+ push dword 0 ; reserved high order 32 bits of EFlags\r
+ pushfd\r
cli ; disable interrupts\r
push gs\r
push fs\r
- DB 6 ; push es\r
- DB 1eh ; push ds\r
- DB 66h, 60h ; pushad\r
+ push es\r
+ push ds\r
+ pushad\r
DB 66h, 0bah ; mov edx, imm32\r
-.ThunkAttr: dd 0\r
+.ThunkAttr: dd 0\r
test dl, THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15\r
jz .1\r
- mov eax, 15cd2401h ; mov ax, 2401h & int 15h\r
+ mov ax, 2401h\r
+ int 15h\r
cli ; disable interrupts\r
jnc .2\r
.1:\r
or al, 2\r
out 92h, al ; deactivate A20M#\r
.2:\r
- xor ax, ax ; xor eax, eax\r
- mov eax, ss ; mov ax, ss\r
- lea bp, [esp + IA32_REGS.size]\r
- ;\r
- ; rsi in the following 2 instructions is indeed bp in 16-bit code\r
- ;\r
- mov [rsi - IA32_REGS.size + IA32_REGS._ESP], bp\r
- DB 66h\r
- mov ebx, [rsi - IA32_REGS.size + IA32_REGS._EIP]\r
- shl ax, 4 ; shl eax, 4\r
- add bp, ax ; add ebp, eax\r
- mov ax, cs\r
- shl ax, 4\r
- lea ax, [eax + ebx + (.64BitCode - .Base)]\r
- DB 66h, 2eh, 89h, 87h ; mov cs:[bx + (.64Eip - .Base)], eax\r
- DW .64Eip - .Base\r
+ xor eax, eax\r
+ mov ax, ss\r
+ lea ebp, [esp + IA32_REGS.size]\r
+ mov [bp - IA32_REGS.size + IA32_REGS._ESP], ebp\r
+ mov ebx, [bp - IA32_REGS.size + IA32_REGS._EIP]\r
+ shl eax, 4 ; shl eax, 4\r
+ add ebp, eax ; add ebp, eax\r
+ mov eax, cs\r
+ shl eax, 4\r
+ lea eax, [eax + ebx + (.64BitCode - .Base)]\r
+ mov [cs:bx + (.64Eip - .Base)], eax\r
DB 66h, 0b8h ; mov eax, imm32\r
.SavedCr4: DD 0\r
- mov cr4, rax\r
- ;\r
- ; rdi in the instruction below is indeed bx in 16-bit code\r
- ;\r
- DB 66h, 2eh ; 2eh is "cs:" segment override\r
- lgdt [rdi + (SavedGdt - .Base)]\r
- DB 66h\r
+ mov cr4, eax\r
+o32 lgdt [cs:bx + (SavedGdt - .Base)]\r
mov ecx, 0c0000080h\r
rdmsr\r
or ah, 1\r
wrmsr\r
DB 66h, 0b8h ; mov eax, imm32\r
.SavedCr0: DD 0\r
- mov cr0, rax\r
+ mov cr0, eax\r
DB 66h, 0eah ; jmp far cs:.64Bit\r
.64Eip: DD 0\r
.SavedCs: DW 0\r
.64BitCode:\r
- db 090h \r
+BITS 64\r
+ nop\r
db 048h, 0bch ; mov rsp, imm64\r
.SavedSp: DQ 0 ; restore stack\r
nop\r
; It will be shadowed to somewhere in memory below 1MB.\r
;------------------------------------------------------------------------------\r
_ToUserCode:\r
- mov ss, edx ; set new segment selectors\r
- mov ds, edx\r
- mov es, edx\r
- mov fs, edx\r
- mov gs, edx\r
- DB 66h\r
+BITS 16\r
+ mov ss, dx ; set new segment selectors\r
+ mov ds, dx\r
+ mov es, dx\r
+ mov fs, dx\r
+ mov gs, dx\r
mov ecx, 0c0000080h\r
- mov cr0, rax ; real mode starts at next instruction\r
+ mov cr0, eax ; real mode starts at next instruction\r
rdmsr\r
and ah, ~1\r
wrmsr\r
- mov cr4, rbp\r
- mov ss, esi ; set up 16-bit stack segment\r
- mov sp, bx ; set up 16-bit stack pointer\r
- DB 66h ; make the following call 32-bit\r
- call .Base ; push eip\r
+ mov cr4, ebp\r
+ mov ss, si ; set up 16-bit stack segment\r
+ mov esp, ebx ; set up 16-bit stack pointer\r
+ call dword .Base ; push eip\r
.Base:\r
- pop bp ; ebp <- address of .Base\r
- push qword [esp + IA32_REGS.size + 2]\r
- lea eax, [rsi + (.RealMode - .Base)] ; rsi is "bp" in 16-bit code\r
- push rax\r
+ pop ebp ; ebp <- address of .Base\r
+ push word [dword esp + IA32_REGS.size + 2]\r
+ lea ax, [bp + (.RealMode - .Base)]\r
+ push ax\r
retf ; execution begins at next instruction\r
.RealMode:\r
- DB 66h, 2eh ; CS and operand size override\r
- lidt [rsi + (_16Idtr - .Base)]\r
- DB 66h, 61h ; popad\r
- DB 1fh ; pop ds\r
- DB 07h ; pop es\r
+\r
+o32 lidt [cs:bp + (_16Idtr - .Base)]\r
+\r
+ popad\r
+ pop ds\r
+ pop es\r
pop fs\r
pop gs\r
- popfw ; popfd\r
- lea sp, [esp + 4] ; skip high order 32 bits of EFlags\r
- DB 66h ; make the following retf 32-bit\r
- retf ; transfer control to user code\r
+ popfd\r
+ lea esp, [esp + 4] ; skip high order 32 bits of EFlags\r
+\r
+o32 retf ; transfer control to user code\r
\r
ALIGN 8\r
\r
;------------------------------------------------------------------------------\r
global ASM_PFX(InternalAsmThunk16)\r
ASM_PFX(InternalAsmThunk16):\r
+BITS 64\r
push rbp\r
push rbx\r
push rsi\r
mov [rcx], ebp ; save CR4 in _BackFromUserCode.SavedCr4\r
and ebp, ~30h ; clear PAE, PSE bits\r
mov esi, r8d ; esi <- 16-bit stack segment\r
- DB 6ah, DATA32 ; push DATA32\r
+ push DATA32\r
pop rdx ; rdx <- 32-bit data segment selector\r
lgdt [rcx + (_16Gdtr - _BackFromUserCode.SavedCr4)]\r
mov ss, edx\r