mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-30 00:54:06 +02:00
1. Added comments to ASM files
2. Fixed a bug in 64-bit AsmDisablePaging64(), which may cause a #GP exception. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2206 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
741fb36417
commit
a9a812a0ed
@ -33,7 +33,7 @@
|
|||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
CpuFlushTlb PROC
|
CpuFlushTlb PROC
|
||||||
mov eax, cr3
|
mov eax, cr3
|
||||||
mov cr3, eax
|
mov cr3, eax ; moving to CR3 flushes TLB
|
||||||
ret
|
ret
|
||||||
CpuFlushTlb ENDP
|
CpuFlushTlb ENDP
|
||||||
|
|
||||||
|
@ -33,18 +33,18 @@
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
InternalMathDivRemU64x32 PROC
|
InternalMathDivRemU64x32 PROC
|
||||||
mov ecx, [esp + 12]
|
mov ecx, [esp + 12] ; ecx <- divisor
|
||||||
mov eax, [esp + 8]
|
mov eax, [esp + 8] ; eax <- dividend[32..63]
|
||||||
xor edx, edx
|
xor edx, edx
|
||||||
div ecx
|
div ecx ; eax <- quotient[32..63], edx <- remainder
|
||||||
push eax
|
push eax
|
||||||
mov eax, [esp + 8]
|
mov eax, [esp + 8] ; eax <- dividend[0..31]
|
||||||
div ecx
|
div ecx ; eax <- quotient[0..31]
|
||||||
mov ecx, [esp + 20]
|
mov ecx, [esp + 20] ; ecx <- Remainder
|
||||||
jecxz @F ; abandon remainder if Remainder == NULL
|
jecxz @F ; abandon remainder if Remainder == NULL
|
||||||
mov [ecx], edx
|
mov [ecx], edx
|
||||||
@@:
|
@@:
|
||||||
pop edx
|
pop edx ; edx <- quotient[32..63]
|
||||||
ret
|
ret
|
||||||
InternalMathDivRemU64x32 ENDP
|
InternalMathDivRemU64x32 ENDP
|
||||||
|
|
||||||
|
@ -36,13 +36,13 @@ EXTERN InternalMathDivRemU64x32:PROC
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
InternalMathDivRemU64x64 PROC
|
InternalMathDivRemU64x64 PROC
|
||||||
mov ecx, [esp + 16]
|
mov ecx, [esp + 16] ; ecx <- divisor[32..63]
|
||||||
test ecx, ecx
|
test ecx, ecx
|
||||||
jnz _@DivRemU64x64 ; call _@DivRemU64x64 if Divisor > 2^32
|
jnz _@DivRemU64x64 ; call _@DivRemU64x64 if Divisor > 2^32
|
||||||
mov ecx, [esp + 20]
|
mov ecx, [esp + 20]
|
||||||
jecxz @F
|
jecxz @F
|
||||||
and dword ptr [ecx + 4], 0
|
and dword ptr [ecx + 4], 0 ; zero high dword of remainder
|
||||||
mov [esp + 16], ecx
|
mov [esp + 16], ecx ; set up stack frame to match DivRemU64x32
|
||||||
@@:
|
@@:
|
||||||
jmp InternalMathDivRemU64x32
|
jmp InternalMathDivRemU64x32
|
||||||
InternalMathDivRemU64x64 ENDP
|
InternalMathDivRemU64x64 ENDP
|
||||||
@ -61,11 +61,11 @@ _@DivRemU64x64 PROC USES ebx esi edi
|
|||||||
jnz @B
|
jnz @B
|
||||||
div ebx
|
div ebx
|
||||||
mov ebx, eax ; ebx <- quotient
|
mov ebx, eax ; ebx <- quotient
|
||||||
mov ecx, [esp + 28]
|
mov ecx, [esp + 28] ; ecx <- high dword of divisor
|
||||||
mul dword ptr [esp + 24]
|
mul dword ptr [esp + 24] ; edx:eax <- quotient * divisor[0..31]
|
||||||
imul ecx, ebx
|
imul ecx, ebx ; ecx <- quotient * divisor[32..63]
|
||||||
add edx, ecx
|
add edx, ecx ; edx <- (quotient * divisor)[32..63]
|
||||||
mov ecx, dword ptr [esp + 32]
|
mov ecx, dword ptr [esp + 32] ; ecx <- addr for Remainder
|
||||||
jc @TooLarge ; product > 2^64
|
jc @TooLarge ; product > 2^64
|
||||||
cmp edi, edx ; compare high 32 bits
|
cmp edi, edx ; compare high 32 bits
|
||||||
ja @Correct
|
ja @Correct
|
||||||
@ -76,7 +76,7 @@ _@DivRemU64x64 PROC USES ebx esi edi
|
|||||||
dec ebx ; adjust quotient by -1
|
dec ebx ; adjust quotient by -1
|
||||||
jecxz @Return ; return if Remainder == NULL
|
jecxz @Return ; return if Remainder == NULL
|
||||||
sub eax, dword ptr [esp + 24]
|
sub eax, dword ptr [esp + 24]
|
||||||
sbb edx, dword ptr [esp + 28]
|
sbb edx, dword ptr [esp + 28] ; edx:eax <- (quotient - 1) * divisor
|
||||||
@Correct:
|
@Correct:
|
||||||
jecxz @Return
|
jecxz @Return
|
||||||
sub esi, eax
|
sub esi, eax
|
||||||
@ -85,7 +85,7 @@ _@DivRemU64x64 PROC USES ebx esi edi
|
|||||||
mov [ecx + 4], edi
|
mov [ecx + 4], edi
|
||||||
@Return:
|
@Return:
|
||||||
mov eax, ebx ; eax <- quotient
|
mov eax, ebx ; eax <- quotient
|
||||||
xor edx, edx
|
xor edx, edx ; quotient is 32 bits long
|
||||||
ret
|
ret
|
||||||
_@DivRemU64x64 ENDP
|
_@DivRemU64x64 ENDP
|
||||||
|
|
||||||
|
@ -40,14 +40,14 @@ InternalX86EnablePaging32 PROC
|
|||||||
mov ecx, [esp + 8]
|
mov ecx, [esp + 8]
|
||||||
mov edx, [esp + 12]
|
mov edx, [esp + 12]
|
||||||
pushfd
|
pushfd
|
||||||
pop edi
|
pop edi ; save flags in edi
|
||||||
cli
|
cli
|
||||||
mov eax, cr0
|
mov eax, cr0
|
||||||
bts eax, 31
|
bts eax, 31
|
||||||
mov esp, [esp + 16]
|
mov esp, [esp + 16]
|
||||||
mov cr0, eax
|
mov cr0, eax
|
||||||
push edi
|
push edi
|
||||||
popfd
|
popfd ; restore flags
|
||||||
push edx
|
push edx
|
||||||
push ecx
|
push ecx
|
||||||
call ebx
|
call ebx
|
||||||
|
@ -47,11 +47,11 @@ InternalX86EnablePaging64 PROC
|
|||||||
or ah, 1 ; set LME
|
or ah, 1 ; set LME
|
||||||
wrmsr
|
wrmsr
|
||||||
mov eax, cr0
|
mov eax, cr0
|
||||||
bts eax, 31
|
bts eax, 31 ; set PG
|
||||||
mov cr0, eax ; enable paging
|
mov cr0, eax ; enable paging
|
||||||
retf
|
retf ; topmost 2 dwords hold the address
|
||||||
@@: ; long mode starts here
|
@@: ; long mode starts here
|
||||||
DB 67h, 48h
|
DB 67h, 48h ; 32-bit address size, 64-bit operand size
|
||||||
mov ebx, [esp] ; mov rbx, [esp]
|
mov ebx, [esp] ; mov rbx, [esp]
|
||||||
DB 67h, 48h
|
DB 67h, 48h
|
||||||
mov ecx, [esp + 8] ; mov rcx, [esp + 8]
|
mov ecx, [esp + 8] ; mov rcx, [esp + 8]
|
||||||
@ -62,7 +62,7 @@ InternalX86EnablePaging64 PROC
|
|||||||
DB 48h
|
DB 48h
|
||||||
add esp, -20h ; add rsp, -20h
|
add esp, -20h ; add rsp, -20h
|
||||||
call ebx ; call rbx
|
call ebx ; call rbx
|
||||||
jmp $
|
hlt ; no one should get here
|
||||||
InternalX86EnablePaging64 ENDP
|
InternalX86EnablePaging64 ENDP
|
||||||
|
|
||||||
END
|
END
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
InternalX86FxRestore PROC
|
InternalX86FxRestore PROC
|
||||||
mov eax, [esp + 4]
|
mov eax, [esp + 4] ; Buffer must be 16-byte aligned
|
||||||
fxrstor [eax]
|
fxrstor [eax]
|
||||||
ret
|
ret
|
||||||
InternalX86FxRestore ENDP
|
InternalX86FxRestore ENDP
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
InternalX86FxSave PROC
|
InternalX86FxSave PROC
|
||||||
mov eax, [esp + 4]
|
mov eax, [esp + 4] ; Buffer must be 16-byte aligned
|
||||||
fxsave [eax]
|
fxsave [eax]
|
||||||
ret
|
ret
|
||||||
InternalX86FxSave ENDP
|
InternalX86FxSave ENDP
|
||||||
|
@ -40,7 +40,7 @@ InternalLongJump PROC
|
|||||||
mov edi, [edx + 8]
|
mov edi, [edx + 8]
|
||||||
mov ebp, [edx + 12]
|
mov ebp, [edx + 12]
|
||||||
mov esp, [edx + 16]
|
mov esp, [edx + 16]
|
||||||
jmp dword ptr [edx + 20]
|
jmp dword ptr [edx + 20] ; restore "eip"
|
||||||
InternalLongJump ENDP
|
InternalLongJump ENDP
|
||||||
|
|
||||||
END
|
END
|
||||||
|
@ -32,15 +32,15 @@
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
InternalMathMultU64x64 PROC USES ebx
|
InternalMathMultU64x64 PROC USES ebx
|
||||||
mov ebx, [esp + 8]
|
mov ebx, [esp + 8] ; ebx <- M1[0..31]
|
||||||
mov edx, [esp + 16]
|
mov edx, [esp + 16] ; edx <- M2[0..31]
|
||||||
mov ecx, ebx
|
mov ecx, ebx
|
||||||
mov eax, edx
|
mov eax, edx
|
||||||
imul ebx, [esp + 20]
|
imul ebx, [esp + 20] ; ebx <- M1[0..31] * M2[32..63]
|
||||||
imul edx, [esp + 12]
|
imul edx, [esp + 12] ; edx <- M1[32..63] * M2[0..31]
|
||||||
add ebx, edx
|
add ebx, edx ; carries are abandoned
|
||||||
mul ecx
|
mul ecx ; edx:eax <- M1[0..31] * M2[0..31]
|
||||||
add edx, ebx
|
add edx, ebx ; carries are abandoned
|
||||||
ret
|
ret
|
||||||
InternalMathMultU64x64 ENDP
|
InternalMathMultU64x64 ENDP
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ InternalMathRRotU64 PROC USES ebx
|
|||||||
rol ebx, cl
|
rol ebx, cl
|
||||||
shrd edx, ebx, cl
|
shrd edx, ebx, cl
|
||||||
test cl, 32 ; Count >= 32?
|
test cl, 32 ; Count >= 32?
|
||||||
cmovnz ecx, eax
|
cmovnz ecx, eax ; switch eax & edx if Count >= 32
|
||||||
cmovnz eax, edx
|
cmovnz eax, edx
|
||||||
cmovnz edx, ecx
|
cmovnz edx, ecx
|
||||||
ret
|
ret
|
||||||
|
@ -32,10 +32,10 @@
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
InternalMathRShiftU64 PROC
|
InternalMathRShiftU64 PROC
|
||||||
mov cl, [esp + 12]
|
mov cl, [esp + 12] ; cl <- Count
|
||||||
xor edx, edx
|
xor edx, edx
|
||||||
mov eax, [esp + 8]
|
mov eax, [esp + 8]
|
||||||
test cl, 32
|
test cl, 32 ; Count >= 32?
|
||||||
cmovz edx, eax
|
cmovz edx, eax
|
||||||
cmovz eax, [esp + 4]
|
cmovz eax, [esp + 4]
|
||||||
shrd eax, edx, cl
|
shrd eax, edx, cl
|
||||||
|
@ -33,6 +33,13 @@
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
AsmReadDr4 PROC
|
AsmReadDr4 PROC
|
||||||
|
;
|
||||||
|
; DR4 is alias to DR6 only if DE (in CR4) is cleared. Otherwise, reading
|
||||||
|
; this register will cause a #UD exception.
|
||||||
|
;
|
||||||
|
; MS assembler doesn't support this instruction since no one would use it
|
||||||
|
; under normal circustances. Here opcode is used.
|
||||||
|
;
|
||||||
DB 0fh, 21h, 0e0h
|
DB 0fh, 21h, 0e0h
|
||||||
ret
|
ret
|
||||||
AsmReadDr4 ENDP
|
AsmReadDr4 ENDP
|
||||||
|
@ -33,6 +33,13 @@
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
AsmReadDr5 PROC
|
AsmReadDr5 PROC
|
||||||
|
;
|
||||||
|
; DR5 is alias to DR7 only if DE (in CR4) is cleared. Otherwise, reading
|
||||||
|
; this register will cause a #UD exception.
|
||||||
|
;
|
||||||
|
; MS assembler doesn't support this instruction since no one would use it
|
||||||
|
; under normal circustances. Here opcode is used.
|
||||||
|
;
|
||||||
DB 0fh, 21h, 0e8h
|
DB 0fh, 21h, 0e8h
|
||||||
ret
|
ret
|
||||||
AsmReadDr5 ENDP
|
AsmReadDr5 ENDP
|
||||||
|
@ -34,16 +34,16 @@ InternalAssertJumpBuffer PROTO C
|
|||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
SetJump PROC
|
SetJump PROC
|
||||||
push [esp + 4]
|
push [esp + 4]
|
||||||
call InternalAssertJumpBuffer
|
call InternalAssertJumpBuffer ; To validate JumpBuffer
|
||||||
pop ecx
|
|
||||||
pop ecx
|
pop ecx
|
||||||
|
pop ecx ; ecx <- return address
|
||||||
mov edx, [esp]
|
mov edx, [esp]
|
||||||
mov [edx], ebx
|
mov [edx], ebx
|
||||||
mov [edx + 4], esi
|
mov [edx + 4], esi
|
||||||
mov [edx + 8], edi
|
mov [edx + 8], edi
|
||||||
mov [edx + 12], ebp
|
mov [edx + 12], ebp
|
||||||
mov [edx + 16], esp
|
mov [edx + 16], esp
|
||||||
mov [edx + 20], ecx
|
mov [edx + 20], ecx ; eip value to restore in LongJump
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
jmp ecx
|
jmp ecx
|
||||||
SetJump ENDP
|
SetJump ENDP
|
||||||
|
@ -33,8 +33,8 @@
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
InternalMathSwapBytes64 PROC
|
InternalMathSwapBytes64 PROC
|
||||||
mov eax, [esp + 8]
|
mov eax, [esp + 8] ; eax <- upper 32 bits
|
||||||
mov edx, [esp + 4]
|
mov edx, [esp + 4] ; edx <- lower 32 bits
|
||||||
bswap eax
|
bswap eax
|
||||||
bswap edx
|
bswap edx
|
||||||
ret
|
ret
|
||||||
|
@ -75,6 +75,11 @@ SavedGdt LABEL FWORD
|
|||||||
; by user code. It will be shadowed to somewhere in memory below 1MB.
|
; by user code. It will be shadowed to somewhere in memory below 1MB.
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
_BackFromUserCode PROC
|
_BackFromUserCode PROC
|
||||||
|
;
|
||||||
|
; The order of saved registers on the stack matches the order they appears
|
||||||
|
; in IA32_REGS structure. This facilitates wrapper function to extract them
|
||||||
|
; into that structure.
|
||||||
|
;
|
||||||
push ss
|
push ss
|
||||||
push cs
|
push cs
|
||||||
DB 66h
|
DB 66h
|
||||||
@ -104,6 +109,11 @@ _ThunkAttr DD ?
|
|||||||
mov eax, ss
|
mov eax, ss
|
||||||
DB 67h
|
DB 67h
|
||||||
lea bp, [esp + sizeof (IA32_REGS)]
|
lea bp, [esp + sizeof (IA32_REGS)]
|
||||||
|
;
|
||||||
|
; esi's in the following 2 instructions are indeed bp in 16-bit code. Fact
|
||||||
|
; is "esi" in 32-bit addressing mode has the same encoding of "bp" in 16-
|
||||||
|
; bit addressing mode.
|
||||||
|
;
|
||||||
mov word ptr (IA32_REGS ptr [esi - sizeof (IA32_REGS)])._ESP, bp
|
mov word ptr (IA32_REGS ptr [esi - sizeof (IA32_REGS)])._ESP, bp
|
||||||
mov ebx, (IA32_REGS ptr [esi - sizeof (IA32_REGS)])._EIP
|
mov ebx, (IA32_REGS ptr [esi - sizeof (IA32_REGS)])._EIP
|
||||||
shl ax, 4 ; shl eax, 4
|
shl ax, 4 ; shl eax, 4
|
||||||
@ -167,7 +177,7 @@ _ToUserCode PROC
|
|||||||
pop fs
|
pop fs
|
||||||
pop gs
|
pop gs
|
||||||
popf ; popfd
|
popf ; popfd
|
||||||
DB 66h
|
DB 66h ; Use 32-bit addressing for "retf" below
|
||||||
retf ; transfer control to user code
|
retf ; transfer control to user code
|
||||||
_ToUserCode ENDP
|
_ToUserCode ENDP
|
||||||
|
|
||||||
@ -197,7 +207,7 @@ GdtEnd LABEL QWORD
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
InternalAsmThunk16 PROC USES ebp ebx esi edi ds es fs gs
|
InternalAsmThunk16 PROC USES ebp ebx esi edi ds es fs gs
|
||||||
mov esi, [esp + 36] ; esi <- RegSet
|
mov esi, [esp + 36] ; esi <- RegSet, the 1st parameter
|
||||||
movzx edx, (IA32_REGS ptr [esi])._SS
|
movzx edx, (IA32_REGS ptr [esi])._SS
|
||||||
mov edi, (IA32_REGS ptr [esi])._ESP
|
mov edi, (IA32_REGS ptr [esi])._ESP
|
||||||
add edi, - (sizeof (IA32_REGS) + 4) ; reserve stack space
|
add edi, - (sizeof (IA32_REGS) + 4) ; reserve stack space
|
||||||
@ -227,11 +237,11 @@ InternalAsmThunk16 PROC USES ebp ebx esi edi ds es fs gs
|
|||||||
push 10h
|
push 10h
|
||||||
pop ecx ; ecx <- selector for data segments
|
pop ecx ; ecx <- selector for data segments
|
||||||
lgdt fword ptr [edx + (_16Gdtr - SavedCr0)]
|
lgdt fword ptr [edx + (_16Gdtr - SavedCr0)]
|
||||||
pushfd
|
pushfd ; Save df/if indeed
|
||||||
call fword ptr [edx + (_EntryPoint - SavedCr0)]
|
call fword ptr [edx + (_EntryPoint - SavedCr0)]
|
||||||
popfd
|
popfd
|
||||||
lidt fword ptr [esp + 36] ; restore protected mode IDTR
|
lidt fword ptr [esp + 36] ; restore protected mode IDTR
|
||||||
lea eax, [ebp - sizeof (IA32_REGS)]
|
lea eax, [ebp - sizeof (IA32_REGS)] ; eax <- the address of IA32_REGS
|
||||||
ret
|
ret
|
||||||
InternalAsmThunk16 ENDP
|
InternalAsmThunk16 ENDP
|
||||||
|
|
||||||
|
@ -34,6 +34,13 @@
|
|||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
AsmWriteDr4 PROC
|
AsmWriteDr4 PROC
|
||||||
mov eax, [esp + 4]
|
mov eax, [esp + 4]
|
||||||
|
;
|
||||||
|
; DR4 is alias to DR6 only if DE (in CR4) is cleared. Otherwise, writing to
|
||||||
|
; this register will cause a #UD exception.
|
||||||
|
;
|
||||||
|
; MS assembler doesn't support this instruction since no one would use it
|
||||||
|
; under normal circustances. Here opcode is used.
|
||||||
|
;
|
||||||
DB 0fh, 23h, 0e0h
|
DB 0fh, 23h, 0e0h
|
||||||
ret
|
ret
|
||||||
AsmWriteDr4 ENDP
|
AsmWriteDr4 ENDP
|
||||||
|
@ -34,6 +34,13 @@
|
|||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
AsmWriteDr5 PROC
|
AsmWriteDr5 PROC
|
||||||
mov eax, [esp + 4]
|
mov eax, [esp + 4]
|
||||||
|
;
|
||||||
|
; DR5 is alias to DR7 only if DE (in CR4) is cleared. Otherwise, writing to
|
||||||
|
; this register will cause a #UD exception.
|
||||||
|
;
|
||||||
|
; MS assembler doesn't support this instruction since no one would use it
|
||||||
|
; under normal circustances. Here opcode is used.
|
||||||
|
;
|
||||||
DB 0fh, 23h, 0e8h
|
DB 0fh, 23h, 0e8h
|
||||||
ret
|
ret
|
||||||
AsmWriteDr5 ENDP
|
AsmWriteDr5 ENDP
|
||||||
|
@ -36,15 +36,14 @@
|
|||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
InternalX86DisablePaging64 PROC
|
InternalX86DisablePaging64 PROC
|
||||||
cli
|
cli
|
||||||
shl rcx, 32
|
shl rcx, 32 ; rcx[32..47] <- Cs
|
||||||
lea eax, @F
|
lea eax, @F
|
||||||
mov ecx, eax
|
|
||||||
push rcx
|
|
||||||
mov ebx, edx
|
|
||||||
mov esi, r8d
|
mov esi, r8d
|
||||||
|
or rcx, rax ; rcx[0..47] <- Cs:@F
|
||||||
mov edi, r9d
|
mov edi, r9d
|
||||||
mov eax, [rsp + 28h]
|
mov eax, [rsp + 28h] ; eax <- New Stack
|
||||||
retf
|
push rcx
|
||||||
|
retf ; switch to compatibility mode
|
||||||
@@:
|
@@:
|
||||||
mov esp, eax ; set up new stack
|
mov esp, eax ; set up new stack
|
||||||
mov rax, cr0
|
mov rax, cr0
|
||||||
@ -57,10 +56,10 @@ InternalX86DisablePaging64 PROC
|
|||||||
mov rax, cr4
|
mov rax, cr4
|
||||||
and al, NOT (1 SHL 5) ; clear PAE
|
and al, NOT (1 SHL 5) ; clear PAE
|
||||||
mov cr4, rax
|
mov cr4, rax
|
||||||
push rdi
|
push rdi ; push Context2
|
||||||
push rsi
|
push rsi ; push Context1
|
||||||
call rbx
|
call rdx ; transfer control to EntryPoint
|
||||||
jmp $
|
hlt ; no one should get here
|
||||||
InternalX86DisablePaging64 ENDP
|
InternalX86DisablePaging64 ENDP
|
||||||
|
|
||||||
END
|
END
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
InternalX86EnablePaging64 PROC
|
InternalX86EnablePaging64 PROC
|
||||||
cli
|
cli
|
||||||
pop rax
|
pop rax ; skip the return address
|
||||||
call @Base
|
call @Base
|
||||||
@Base:
|
@Base:
|
||||||
add dword ptr [rsp], @F - @Base ; offset for far retf, seg is the 1st arg
|
add dword ptr [rsp], @F - @Base ; offset for far retf, seg is the 1st arg
|
||||||
@ -58,7 +58,7 @@ InternalX86EnablePaging64 PROC
|
|||||||
mov rsp, [esp + 18h]
|
mov rsp, [esp + 18h]
|
||||||
add rsp, -20h
|
add rsp, -20h
|
||||||
call rbx
|
call rbx
|
||||||
jmp $ ; halt processor if EntryPoint() returned
|
hlt ; halt processor if EntryPoint() returned
|
||||||
InternalX86EnablePaging64 ENDP
|
InternalX86EnablePaging64 ENDP
|
||||||
|
|
||||||
END
|
END
|
||||||
|
@ -39,7 +39,7 @@ InternalLongJump PROC
|
|||||||
mov r13, [rcx + 30h]
|
mov r13, [rcx + 30h]
|
||||||
mov r14, [rcx + 38h]
|
mov r14, [rcx + 38h]
|
||||||
mov r15, [rcx + 40h]
|
mov r15, [rcx + 40h]
|
||||||
mov rax, rdx
|
mov rax, rdx ; set return value
|
||||||
jmp qword ptr [rcx + 48h]
|
jmp qword ptr [rcx + 48h]
|
||||||
InternalLongJump ENDP
|
InternalLongJump ENDP
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ AsmMonitor PROC
|
|||||||
mov eax, ecx
|
mov eax, ecx
|
||||||
mov ecx, edx
|
mov ecx, edx
|
||||||
mov edx, r8d
|
mov edx, r8d
|
||||||
DB 0fh, 1, 0c8h
|
DB 0fh, 1, 0c8h ; monitor
|
||||||
ret
|
ret
|
||||||
AsmMonitor ENDP
|
AsmMonitor ENDP
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
AsmMwait PROC
|
AsmMwait PROC
|
||||||
mov eax, ecx
|
mov eax, ecx
|
||||||
mov ecx, edx
|
mov ecx, edx
|
||||||
DB 0fh, 1, 0c9h
|
DB 0fh, 1, 0c9h ; mwait
|
||||||
ret
|
ret
|
||||||
AsmMwait ENDP
|
AsmMwait ENDP
|
||||||
|
|
||||||
|
@ -31,6 +31,10 @@
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
AsmReadDr4 PROC
|
AsmReadDr4 PROC
|
||||||
|
;
|
||||||
|
; There's no obvious reason to access this register, since it's aliased to
|
||||||
|
; DR7 when DE=0 or an exception generated when DE=1
|
||||||
|
;
|
||||||
DB 0fh, 21h, 0e0h
|
DB 0fh, 21h, 0e0h
|
||||||
ret
|
ret
|
||||||
AsmReadDr4 ENDP
|
AsmReadDr4 ENDP
|
||||||
|
@ -31,6 +31,10 @@
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
AsmReadDr5 PROC
|
AsmReadDr5 PROC
|
||||||
|
;
|
||||||
|
; There's no obvious reason to access this register, since it's aliased to
|
||||||
|
; DR7 when DE=0 or an exception generated when DE=1
|
||||||
|
;
|
||||||
DB 0fh, 21h, 0e8h
|
DB 0fh, 21h, 0e8h
|
||||||
ret
|
ret
|
||||||
AsmReadDr5 ENDP
|
AsmReadDr5 ENDP
|
||||||
|
@ -31,6 +31,9 @@
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
AsmReadMm0 PROC
|
AsmReadMm0 PROC
|
||||||
|
;
|
||||||
|
; 64-bit MASM doesn't support MMX instructions, so use opcode here
|
||||||
|
;
|
||||||
DB 48h, 0fh, 7eh, 0c0h
|
DB 48h, 0fh, 7eh, 0c0h
|
||||||
ret
|
ret
|
||||||
AsmReadMm0 ENDP
|
AsmReadMm0 ENDP
|
||||||
|
@ -31,6 +31,9 @@
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
AsmReadMm1 PROC
|
AsmReadMm1 PROC
|
||||||
|
;
|
||||||
|
; 64-bit MASM doesn't support MMX instructions, so use opcode here
|
||||||
|
;
|
||||||
DB 48h, 0fh, 7eh, 0c8h
|
DB 48h, 0fh, 7eh, 0c8h
|
||||||
ret
|
ret
|
||||||
AsmReadMm1 ENDP
|
AsmReadMm1 ENDP
|
||||||
|
@ -31,6 +31,9 @@
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
AsmReadMm2 PROC
|
AsmReadMm2 PROC
|
||||||
|
;
|
||||||
|
; 64-bit MASM doesn't support MMX instructions, so use opcode here
|
||||||
|
;
|
||||||
DB 48h, 0fh, 7eh, 0d0h
|
DB 48h, 0fh, 7eh, 0d0h
|
||||||
ret
|
ret
|
||||||
AsmReadMm2 ENDP
|
AsmReadMm2 ENDP
|
||||||
|
@ -31,6 +31,9 @@
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
AsmReadMm3 PROC
|
AsmReadMm3 PROC
|
||||||
|
;
|
||||||
|
; 64-bit MASM doesn't support MMX instructions, so use opcode here
|
||||||
|
;
|
||||||
DB 48h, 0fh, 7eh, 0d8h
|
DB 48h, 0fh, 7eh, 0d8h
|
||||||
ret
|
ret
|
||||||
AsmReadMm3 ENDP
|
AsmReadMm3 ENDP
|
||||||
|
@ -31,6 +31,9 @@
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
AsmReadMm4 PROC
|
AsmReadMm4 PROC
|
||||||
|
;
|
||||||
|
; 64-bit MASM doesn't support MMX instructions, so use opcode here
|
||||||
|
;
|
||||||
DB 48h, 0fh, 7eh, 0e0h
|
DB 48h, 0fh, 7eh, 0e0h
|
||||||
ret
|
ret
|
||||||
AsmReadMm4 ENDP
|
AsmReadMm4 ENDP
|
||||||
|
@ -31,6 +31,9 @@
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
AsmReadMm5 PROC
|
AsmReadMm5 PROC
|
||||||
|
;
|
||||||
|
; 64-bit MASM doesn't support MMX instructions, so use opcode here
|
||||||
|
;
|
||||||
DB 48h, 0fh, 7eh, 0e8h
|
DB 48h, 0fh, 7eh, 0e8h
|
||||||
ret
|
ret
|
||||||
AsmReadMm5 ENDP
|
AsmReadMm5 ENDP
|
||||||
|
@ -31,6 +31,9 @@
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
AsmReadMm6 PROC
|
AsmReadMm6 PROC
|
||||||
|
;
|
||||||
|
; 64-bit MASM doesn't support MMX instructions, so use opcode here
|
||||||
|
;
|
||||||
DB 48h, 0fh, 7eh, 0f0h
|
DB 48h, 0fh, 7eh, 0f0h
|
||||||
ret
|
ret
|
||||||
AsmReadMm6 ENDP
|
AsmReadMm6 ENDP
|
||||||
|
@ -31,6 +31,9 @@
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
AsmReadMm7 PROC
|
AsmReadMm7 PROC
|
||||||
|
;
|
||||||
|
; 64-bit MASM doesn't support MMX instructions, so use opcode here
|
||||||
|
;
|
||||||
DB 48h, 0fh, 7eh, 0f8h
|
DB 48h, 0fh, 7eh, 0f8h
|
||||||
ret
|
ret
|
||||||
AsmReadMm7 ENDP
|
AsmReadMm7 ENDP
|
||||||
|
@ -66,6 +66,14 @@ SavedGdt LABEL FWORD
|
|||||||
; by user code. It will be shadowed to somewhere in memory below 1MB.
|
; by user code. It will be shadowed to somewhere in memory below 1MB.
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
_BackFromUserCode PROC
|
_BackFromUserCode PROC
|
||||||
|
;
|
||||||
|
; The order of saved registers on the stack matches the order they appears
|
||||||
|
; in IA32_REGS structure. This facilitates wrapper function to extract them
|
||||||
|
; into that structure.
|
||||||
|
;
|
||||||
|
; Some instructions for manipulation of segment registers have to be written
|
||||||
|
; in opcode since 64-bit MASM prevents accesses to those registers.
|
||||||
|
;
|
||||||
DB 16h ; push ss
|
DB 16h ; push ss
|
||||||
DB 0eh ; push cs
|
DB 0eh ; push cs
|
||||||
DB 66h
|
DB 66h
|
||||||
@ -115,7 +123,7 @@ SavedCr4 DD ?
|
|||||||
;
|
;
|
||||||
; rdi in the instruction below is indeed bx in 16-bit code
|
; rdi in the instruction below is indeed bx in 16-bit code
|
||||||
;
|
;
|
||||||
DB 66h, 2eh
|
DB 66h, 2eh ; 2eh is "cs:" segment override
|
||||||
lgdt fword ptr [rdi + (SavedGdt - @Base)]
|
lgdt fword ptr [rdi + (SavedGdt - @Base)]
|
||||||
DB 66h
|
DB 66h
|
||||||
mov ecx, 0c0000080h
|
mov ecx, 0c0000080h
|
||||||
@ -129,9 +137,8 @@ SavedCr0 DD ?
|
|||||||
@64Eip DD ?
|
@64Eip DD ?
|
||||||
SavedCs DW ?
|
SavedCs DW ?
|
||||||
@64BitCode:
|
@64BitCode:
|
||||||
DB 48h, 0b8h ; mov rax, imm64
|
mov rsp, r8 ; restore stack
|
||||||
SavedRip DQ ?
|
ret
|
||||||
jmp rax ; return to caller
|
|
||||||
_BackFromUserCode ENDP
|
_BackFromUserCode ENDP
|
||||||
|
|
||||||
_EntryPoint DD _ToUserCode - m16Start
|
_EntryPoint DD _ToUserCode - m16Start
|
||||||
@ -160,14 +167,14 @@ _ToUserCode PROC
|
|||||||
mov cr4, rbp
|
mov cr4, rbp
|
||||||
mov ss, esi ; set up 16-bit stack segment
|
mov ss, esi ; set up 16-bit stack segment
|
||||||
mov sp, bx ; set up 16-bit stack pointer
|
mov sp, bx ; set up 16-bit stack pointer
|
||||||
DB 66h
|
DB 66h ; make the following call 32-bit
|
||||||
call @Base ; push eip
|
call @Base ; push eip
|
||||||
@Base:
|
@Base:
|
||||||
pop bp ; ebp <- address of @Base
|
pop bp ; ebp <- address of @Base
|
||||||
push [esp + sizeof (IA32_REGS) + 2]
|
push [esp + sizeof (IA32_REGS) + 2]
|
||||||
lea eax, [rsi + (@RealMode - @Base)]
|
lea eax, [rsi + (@RealMode - @Base)] ; rsi is "bp" in 16-bit code
|
||||||
push rax
|
push rax
|
||||||
retf
|
retf ; execution begins at next instruction
|
||||||
@RealMode:
|
@RealMode:
|
||||||
DB 66h, 2eh ; CS and operand size override
|
DB 66h, 2eh ; CS and operand size override
|
||||||
lidt fword ptr [rsi + (_16Idtr - @Base)]
|
lidt fword ptr [rsi + (_16Idtr - @Base)]
|
||||||
@ -178,7 +185,7 @@ _ToUserCode PROC
|
|||||||
pop gs
|
pop gs
|
||||||
popf ; popfd
|
popf ; popfd
|
||||||
lea sp, [esp + 4] ; skip high order 32 bits of EFlags
|
lea sp, [esp + 4] ; skip high order 32 bits of EFlags
|
||||||
DB 66h
|
DB 66h ; make the following retf 32-bit
|
||||||
retf ; transfer control to user code
|
retf ; transfer control to user code
|
||||||
_ToUserCode ENDP
|
_ToUserCode ENDP
|
||||||
|
|
||||||
@ -220,8 +227,8 @@ GDT_SIZE = $ - _NullSeg
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
InternalAsmThunk16 PROC USES rbp rbx rsi rdi
|
InternalAsmThunk16 PROC USES rbp rbx rsi rdi
|
||||||
mov r10d, ds
|
mov r10d, ds ; r9 ~ r11 are not accessible in 16-bit
|
||||||
mov r11d, es
|
mov r11d, es ; so use them for saving seg registers
|
||||||
mov r9d, ss
|
mov r9d, ss
|
||||||
push fs
|
push fs
|
||||||
push gs
|
push gs
|
||||||
@ -238,8 +245,8 @@ InternalAsmThunk16 PROC USES rbp rbx rsi rdi
|
|||||||
lea ecx, [rdx + (SavedCr4 - m16Start)]
|
lea ecx, [rdx + (SavedCr4 - m16Start)]
|
||||||
mov eax, edx ; eax <- transition code address
|
mov eax, edx ; eax <- transition code address
|
||||||
and edx, 0fh
|
and edx, 0fh
|
||||||
shl eax, 12
|
shl eax, 12 ; segment address in high order 16 bits
|
||||||
lea ax, [rdx + (_BackFromUserCode - m16Start)]
|
lea ax, [rdx + (_BackFromUserCode - m16Start)] ; offset address
|
||||||
stosd ; [edi] <- return address of user code
|
stosd ; [edi] <- return address of user code
|
||||||
sgdt fword ptr [rcx + (SavedGdt - SavedCr4)]
|
sgdt fword ptr [rcx + (SavedGdt - SavedCr4)]
|
||||||
sidt fword ptr [rsp + 38h] ; save IDT stack in argument space
|
sidt fword ptr [rsp + 38h] ; save IDT stack in argument space
|
||||||
@ -257,13 +264,12 @@ InternalAsmThunk16 PROC USES rbp rbx rsi rdi
|
|||||||
pushfq
|
pushfq
|
||||||
lea edx, [rdx + DATA16 - DATA32]
|
lea edx, [rdx + DATA16 - DATA32]
|
||||||
lea r8, @RetFromRealMode
|
lea r8, @RetFromRealMode
|
||||||
mov [rcx + (SavedRip - SavedCr4)], r8
|
push r8
|
||||||
mov r8d, cs
|
mov r8d, cs
|
||||||
mov [rcx + (SavedCs - SavedCr4)], r8w
|
mov [rcx + (SavedCs - SavedCr4)], r8w
|
||||||
mov r8, rsp
|
mov r8, rsp
|
||||||
jmp fword ptr [rcx + (_EntryPoint - SavedCr4)]
|
jmp fword ptr [rcx + (_EntryPoint - SavedCr4)]
|
||||||
@RetFromRealMode:
|
@RetFromRealMode:
|
||||||
mov rsp, r8
|
|
||||||
popfq
|
popfq
|
||||||
lidt fword ptr [rsp + 38h] ; restore protected mode IDTR
|
lidt fword ptr [rsp + 38h] ; restore protected mode IDTR
|
||||||
lea eax, [rbp - sizeof (IA32_REGS)]
|
lea eax, [rbp - sizeof (IA32_REGS)]
|
||||||
|
@ -31,6 +31,10 @@
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
AsmWriteDr4 PROC
|
AsmWriteDr4 PROC
|
||||||
|
;
|
||||||
|
; There's no obvious reason to access this register, since it's aliased to
|
||||||
|
; DR6 when DE=0 or an exception generated when DE=1
|
||||||
|
;
|
||||||
DB 0fh, 23h, 0e1h
|
DB 0fh, 23h, 0e1h
|
||||||
mov rax, rcx
|
mov rax, rcx
|
||||||
ret
|
ret
|
||||||
|
@ -31,6 +31,10 @@
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
AsmWriteDr5 PROC
|
AsmWriteDr5 PROC
|
||||||
|
;
|
||||||
|
; There's no obvious reason to access this register, since it's aliased to
|
||||||
|
; DR7 when DE=0 or an exception generated when DE=1
|
||||||
|
;
|
||||||
DB 0fh, 23h, 0e9h
|
DB 0fh, 23h, 0e9h
|
||||||
mov rax, rcx
|
mov rax, rcx
|
||||||
ret
|
ret
|
||||||
|
@ -31,6 +31,9 @@
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
AsmWriteMm0 PROC
|
AsmWriteMm0 PROC
|
||||||
|
;
|
||||||
|
; 64-bit MASM doesn't support MMX instructions, so use opcode here
|
||||||
|
;
|
||||||
DB 48h, 0fh, 6eh, 0c1h
|
DB 48h, 0fh, 6eh, 0c1h
|
||||||
ret
|
ret
|
||||||
AsmWriteMm0 ENDP
|
AsmWriteMm0 ENDP
|
||||||
|
@ -31,6 +31,9 @@
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
AsmWriteMm1 PROC
|
AsmWriteMm1 PROC
|
||||||
|
;
|
||||||
|
; 64-bit MASM doesn't support MMX instructions, so use opcode here
|
||||||
|
;
|
||||||
DB 48h, 0fh, 6eh, 0c9h
|
DB 48h, 0fh, 6eh, 0c9h
|
||||||
ret
|
ret
|
||||||
AsmWriteMm1 ENDP
|
AsmWriteMm1 ENDP
|
||||||
|
@ -31,6 +31,9 @@
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
AsmWriteMm2 PROC
|
AsmWriteMm2 PROC
|
||||||
|
;
|
||||||
|
; 64-bit MASM doesn't support MMX instructions, so use opcode here
|
||||||
|
;
|
||||||
DB 48h, 0fh, 6eh, 0d1h
|
DB 48h, 0fh, 6eh, 0d1h
|
||||||
ret
|
ret
|
||||||
AsmWriteMm2 ENDP
|
AsmWriteMm2 ENDP
|
||||||
|
@ -31,6 +31,9 @@
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
AsmWriteMm3 PROC
|
AsmWriteMm3 PROC
|
||||||
|
;
|
||||||
|
; 64-bit MASM doesn't support MMX instructions, so use opcode here
|
||||||
|
;
|
||||||
DB 48h, 0fh, 6eh, 0d9h
|
DB 48h, 0fh, 6eh, 0d9h
|
||||||
ret
|
ret
|
||||||
AsmWriteMm3 ENDP
|
AsmWriteMm3 ENDP
|
||||||
|
@ -31,6 +31,9 @@
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
AsmWriteMm4 PROC
|
AsmWriteMm4 PROC
|
||||||
|
;
|
||||||
|
; 64-bit MASM doesn't support MMX instructions, so use opcode here
|
||||||
|
;
|
||||||
DB 48h, 0fh, 6eh, 0e1h
|
DB 48h, 0fh, 6eh, 0e1h
|
||||||
ret
|
ret
|
||||||
AsmWriteMm4 ENDP
|
AsmWriteMm4 ENDP
|
||||||
|
@ -31,6 +31,9 @@
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
AsmWriteMm5 PROC
|
AsmWriteMm5 PROC
|
||||||
|
;
|
||||||
|
; 64-bit MASM doesn't support MMX instructions, so use opcode here
|
||||||
|
;
|
||||||
DB 48h, 0fh, 6eh, 0e9h
|
DB 48h, 0fh, 6eh, 0e9h
|
||||||
ret
|
ret
|
||||||
AsmWriteMm5 ENDP
|
AsmWriteMm5 ENDP
|
||||||
|
@ -31,6 +31,9 @@
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
AsmWriteMm6 PROC
|
AsmWriteMm6 PROC
|
||||||
|
;
|
||||||
|
; 64-bit MASM doesn't support MMX instructions, so use opcode here
|
||||||
|
;
|
||||||
DB 48h, 0fh, 6eh, 0f1h
|
DB 48h, 0fh, 6eh, 0f1h
|
||||||
ret
|
ret
|
||||||
AsmWriteMm6 ENDP
|
AsmWriteMm6 ENDP
|
||||||
|
@ -31,6 +31,9 @@
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
AsmWriteMm7 PROC
|
AsmWriteMm7 PROC
|
||||||
|
;
|
||||||
|
; 64-bit MASM doesn't support MMX instructions, so use opcode here
|
||||||
|
;
|
||||||
DB 48h, 0fh, 6eh, 0f9h
|
DB 48h, 0fh, 6eh, 0f9h
|
||||||
ret
|
ret
|
||||||
AsmWriteMm7 ENDP
|
AsmWriteMm7 ENDP
|
||||||
|
@ -32,8 +32,8 @@
|
|||||||
; );
|
; );
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
AsmWriteMsr64 PROC
|
AsmWriteMsr64 PROC
|
||||||
mov rax, rdx
|
mov rax, rdx ; meanwhile, rax <- return value
|
||||||
shr rdx, 20h
|
shr rdx, 20h ; edx:eax contains the value to write
|
||||||
wrmsr
|
wrmsr
|
||||||
ret
|
ret
|
||||||
AsmWriteMsr64 ENDP
|
AsmWriteMsr64 ENDP
|
||||||
|
Loading…
x
Reference in New Issue
Block a user