1. Added comments to ASM files
authorbxing <bxing@de2fecce-e211-0410-80a6-f3fac2684e05>
Wed, 10 Jan 2007 06:57:04 +0000 (06:57 +0000)
committerbxing <bxing@de2fecce-e211-0410-80a6-f3fac2684e05>
Wed, 10 Jan 2007 06:57:04 +0000 (06:57 +0000)
2. Fixed a bug in 64-bit AsmDisablePaging64(), which may cause a #GP exception.

git-svn-id: https://edk2.tianocore.org/svn/edk2/trunk@2206 de2fecce-e211-0410-80a6-f3fac2684e05

45 files changed:
edk2/MdePkg/Library/BaseLib/Ia32/CpuFlushTlb.asm
edk2/MdePkg/Library/BaseLib/Ia32/DivU64x32Remainder.asm
edk2/MdePkg/Library/BaseLib/Ia32/DivU64x64Remainder.asm
edk2/MdePkg/Library/BaseLib/Ia32/EnablePaging32.asm
edk2/MdePkg/Library/BaseLib/Ia32/EnablePaging64.asm
edk2/MdePkg/Library/BaseLib/Ia32/FxRestore.asm
edk2/MdePkg/Library/BaseLib/Ia32/FxSave.asm
edk2/MdePkg/Library/BaseLib/Ia32/LongJump.asm
edk2/MdePkg/Library/BaseLib/Ia32/MultU64x64.asm
edk2/MdePkg/Library/BaseLib/Ia32/RRotU64.asm
edk2/MdePkg/Library/BaseLib/Ia32/RShiftU64.asm
edk2/MdePkg/Library/BaseLib/Ia32/ReadDr4.asm
edk2/MdePkg/Library/BaseLib/Ia32/ReadDr5.asm
edk2/MdePkg/Library/BaseLib/Ia32/SetJump.asm
edk2/MdePkg/Library/BaseLib/Ia32/SwapBytes64.asm
edk2/MdePkg/Library/BaseLib/Ia32/Thunk16.asm
edk2/MdePkg/Library/BaseLib/Ia32/WriteDr4.asm
edk2/MdePkg/Library/BaseLib/Ia32/WriteDr5.asm
edk2/MdePkg/Library/BaseLib/X64/DisablePaging64.asm
edk2/MdePkg/Library/BaseLib/X64/EnablePaging64.asm
edk2/MdePkg/Library/BaseLib/X64/LongJump.asm
edk2/MdePkg/Library/BaseLib/X64/Monitor.asm
edk2/MdePkg/Library/BaseLib/X64/Mwait.asm
edk2/MdePkg/Library/BaseLib/X64/ReadDr4.asm
edk2/MdePkg/Library/BaseLib/X64/ReadDr5.asm
edk2/MdePkg/Library/BaseLib/X64/ReadMm0.asm
edk2/MdePkg/Library/BaseLib/X64/ReadMm1.asm
edk2/MdePkg/Library/BaseLib/X64/ReadMm2.asm
edk2/MdePkg/Library/BaseLib/X64/ReadMm3.asm
edk2/MdePkg/Library/BaseLib/X64/ReadMm4.asm
edk2/MdePkg/Library/BaseLib/X64/ReadMm5.asm
edk2/MdePkg/Library/BaseLib/X64/ReadMm6.asm
edk2/MdePkg/Library/BaseLib/X64/ReadMm7.asm
edk2/MdePkg/Library/BaseLib/X64/Thunk16.asm
edk2/MdePkg/Library/BaseLib/X64/WriteDr4.asm
edk2/MdePkg/Library/BaseLib/X64/WriteDr5.asm
edk2/MdePkg/Library/BaseLib/X64/WriteMm0.asm
edk2/MdePkg/Library/BaseLib/X64/WriteMm1.asm
edk2/MdePkg/Library/BaseLib/X64/WriteMm2.asm
edk2/MdePkg/Library/BaseLib/X64/WriteMm3.asm
edk2/MdePkg/Library/BaseLib/X64/WriteMm4.asm
edk2/MdePkg/Library/BaseLib/X64/WriteMm5.asm
edk2/MdePkg/Library/BaseLib/X64/WriteMm6.asm
edk2/MdePkg/Library/BaseLib/X64/WriteMm7.asm
edk2/MdePkg/Library/BaseLib/X64/WriteMsr64.asm

index 3674124..4f0c4f9 100644 (file)
@@ -33,7 +33,7 @@
 ;------------------------------------------------------------------------------\r
 CpuFlushTlb PROC\r
     mov     eax, cr3\r
-    mov     cr3, eax\r
+    mov     cr3, eax                    ; moving to CR3 flushes TLB\r
     ret\r
 CpuFlushTlb ENDP\r
 \r
index a836e22..e025b22 100644 (file)
 ;   );\r
 ;------------------------------------------------------------------------------\r
 InternalMathDivRemU64x32    PROC\r
-    mov     ecx, [esp + 12]\r
-    mov     eax, [esp + 8]\r
+    mov     ecx, [esp + 12]         ; ecx <- divisor\r
+    mov     eax, [esp + 8]          ; eax <- dividend[32..63]\r
     xor     edx, edx\r
-    div     ecx\r
+    div     ecx                     ; eax <- quotient[32..63], edx <- remainder\r
     push    eax\r
-    mov     eax, [esp + 8]\r
-    div     ecx\r
-    mov     ecx, [esp + 20]\r
+    mov     eax, [esp + 8]          ; eax <- dividend[0..31]\r
+    div     ecx                     ; eax <- quotient[0..31]\r
+    mov     ecx, [esp + 20]         ; ecx <- Remainder\r
     jecxz   @F                      ; abandon remainder if Remainder == NULL\r
     mov     [ecx], edx\r
 @@:\r
-    pop     edx\r
+    pop     edx                     ; edx <- quotient[32..63]\r
     ret\r
 InternalMathDivRemU64x32    ENDP\r
 \r
index 61a53d1..95e57ef 100644 (file)
@@ -36,13 +36,13 @@ EXTERN  InternalMathDivRemU64x32:PROC
 ;   );\r
 ;------------------------------------------------------------------------------\r
 InternalMathDivRemU64x64    PROC\r
-    mov     ecx, [esp + 16]\r
+    mov     ecx, [esp + 16]             ; ecx <- divisor[32..63]\r
     test    ecx, ecx\r
     jnz     _@DivRemU64x64              ; call _@DivRemU64x64 if Divisor > 2^32\r
     mov     ecx, [esp + 20]\r
     jecxz   @F\r
-    and     dword ptr [ecx + 4], 0\r
-    mov     [esp + 16], ecx\r
+    and     dword ptr [ecx + 4], 0      ; zero high dword of remainder\r
+    mov     [esp + 16], ecx             ; set up stack frame to match DivRemU64x32\r
 @@:\r
     jmp     InternalMathDivRemU64x32\r
 InternalMathDivRemU64x64    ENDP\r
@@ -61,11 +61,11 @@ _@DivRemU64x64  PROC    USES    ebx esi edi
     jnz     @B\r
     div     ebx\r
     mov     ebx, eax                    ; ebx <- quotient\r
-    mov     ecx, [esp + 28]\r
-    mul     dword ptr [esp + 24]\r
-    imul    ecx, ebx\r
-    add     edx, ecx\r
-    mov     ecx, dword ptr [esp + 32]\r
+    mov     ecx, [esp + 28]             ; ecx <- high dword of divisor\r
+    mul     dword ptr [esp + 24]        ; edx:eax <- quotient * divisor[0..31]\r
+    imul    ecx, ebx                    ; ecx <- quotient * divisor[32..63]\r
+    add     edx, ecx                    ; edx <- (quotient * divisor)[32..63]\r
+    mov     ecx, dword ptr [esp + 32]   ; ecx <- addr for Remainder\r
     jc      @TooLarge                   ; product > 2^64\r
     cmp     edi, edx                    ; compare high 32 bits\r
     ja      @Correct\r
@@ -76,7 +76,7 @@ _@DivRemU64x64  PROC    USES    ebx esi edi
     dec     ebx                         ; adjust quotient by -1\r
     jecxz   @Return                     ; return if Remainder == NULL\r
     sub     eax, dword ptr [esp + 24]\r
-    sbb     edx, dword ptr [esp + 28]\r
+    sbb     edx, dword ptr [esp + 28]   ; edx:eax <- (quotient - 1) * divisor\r
 @Correct:\r
     jecxz   @Return\r
     sub     esi, eax\r
@@ -85,7 +85,7 @@ _@DivRemU64x64  PROC    USES    ebx esi edi
     mov     [ecx + 4], edi\r
 @Return:\r
     mov     eax, ebx                    ; eax <- quotient\r
-    xor     edx, edx\r
+    xor     edx, edx                    ; quotient is 32 bits long\r
     ret\r
 _@DivRemU64x64  ENDP\r
 \r
index cf6f2fe..ae98b93 100644 (file)
@@ -40,14 +40,14 @@ InternalX86EnablePaging32 PROC
     mov     ecx, [esp + 8]\r
     mov     edx, [esp + 12]\r
     pushfd\r
-    pop     edi\r
+    pop     edi                         ; save flags in edi\r
     cli\r
     mov     eax, cr0\r
     bts     eax, 31\r
     mov     esp, [esp + 16]\r
     mov     cr0, eax\r
     push    edi\r
-    popfd\r
+    popfd                               ; restore flags\r
     push    edx\r
     push    ecx\r
     call    ebx\r
index 354d1fe..435bb39 100644 (file)
@@ -47,11 +47,11 @@ InternalX86EnablePaging64 PROC
     or      ah, 1                       ; set LME\r
     wrmsr\r
     mov     eax, cr0\r
-    bts     eax, 31\r
+    bts     eax, 31                     ; set PG\r
     mov     cr0, eax                    ; enable paging\r
-    retf\r
+    retf                                ; topmost 2 dwords hold the address\r
 @@:                                     ; long mode starts here\r
-    DB      67h, 48h\r
+    DB      67h, 48h                    ; 32-bit address size, 64-bit operand size\r
     mov     ebx, [esp]                  ; mov rbx, [esp]\r
     DB      67h, 48h\r
     mov     ecx, [esp + 8]              ; mov rcx, [esp + 8]\r
@@ -62,7 +62,7 @@ InternalX86EnablePaging64 PROC
     DB      48h\r
     add     esp, -20h                   ; add rsp, -20h\r
     call    ebx                         ; call rbx\r
-    jmp     $\r
+    hlt                                 ; no one should get here\r
 InternalX86EnablePaging64 ENDP\r
 \r
     END\r
index 9bcc6ac..5def311 100644 (file)
@@ -34,7 +34,7 @@
 ;   );\r
 ;------------------------------------------------------------------------------\r
 InternalX86FxRestore  PROC\r
-    mov     eax, [esp + 4]\r
+    mov     eax, [esp + 4]              ; Buffer must be 16-byte aligned\r
     fxrstor [eax]\r
     ret\r
 InternalX86FxRestore  ENDP\r
index 7d5ea45..d3a9f9c 100644 (file)
@@ -34,7 +34,7 @@
 ;   );\r
 ;------------------------------------------------------------------------------\r
 InternalX86FxSave PROC\r
-    mov     eax, [esp + 4]\r
+    mov     eax, [esp + 4]              ; Buffer must be 16-byte aligned\r
     fxsave  [eax]\r
     ret\r
 InternalX86FxSave ENDP\r
index a634c45..0309f6a 100644 (file)
@@ -40,7 +40,7 @@ InternalLongJump    PROC
     mov     edi, [edx + 8]\r
     mov     ebp, [edx + 12]\r
     mov     esp, [edx + 16]\r
-    jmp     dword ptr [edx + 20]\r
+    jmp     dword ptr [edx + 20]        ; restore "eip"\r
 InternalLongJump    ENDP\r
 \r
     END\r
index 377aa51..f367954 100644 (file)
 ;   );\r
 ;------------------------------------------------------------------------------\r
 InternalMathMultU64x64  PROC    USES    ebx\r
-    mov     ebx, [esp + 8]\r
-    mov     edx, [esp + 16]\r
+    mov     ebx, [esp + 8]              ; ebx <- M1[0..31]\r
+    mov     edx, [esp + 16]             ; edx <- M2[0..31]\r
     mov     ecx, ebx\r
     mov     eax, edx\r
-    imul    ebx, [esp + 20]\r
-    imul    edx, [esp + 12]\r
-    add     ebx, edx\r
-    mul     ecx\r
-    add     edx, ebx\r
+    imul    ebx, [esp + 20]             ; ebx <- M1[0..31] * M2[32..63]\r
+    imul    edx, [esp + 12]             ; edx <- M1[32..63] * M2[0..31]\r
+    add     ebx, edx                    ; carries are abandoned\r
+    mul     ecx                         ; edx:eax <- M1[0..31] * M2[0..31]\r
+    add     edx, ebx                    ; carries are abandoned\r
     ret\r
 InternalMathMultU64x64  ENDP\r
 \r
index 4c58878..fe13abc 100644 (file)
@@ -40,7 +40,7 @@ InternalMathRRotU64 PROC    USES    ebx
     rol     ebx, cl\r
     shrd    edx, ebx, cl\r
     test    cl, 32                      ; Count >= 32?\r
-    cmovnz  ecx, eax\r
+    cmovnz  ecx, eax                    ; switch eax & edx if Count >= 32\r
     cmovnz  eax, edx\r
     cmovnz  edx, ecx\r
     ret\r
index 793a8f9..faa4e96 100644 (file)
 ;   );\r
 ;------------------------------------------------------------------------------\r
 InternalMathRShiftU64   PROC\r
-    mov     cl, [esp + 12]\r
+    mov     cl, [esp + 12]              ; cl <- Count\r
     xor     edx, edx\r
     mov     eax, [esp + 8]\r
-    test    cl, 32\r
+    test    cl, 32                      ; Count >= 32?\r
     cmovz   edx, eax\r
     cmovz   eax, [esp + 4]\r
     shrd    eax, edx, cl\r
index d1fffe4..606f26f 100644 (file)
 ;   );\r
 ;------------------------------------------------------------------------------\r
 AsmReadDr4  PROC\r
+    ;\r
+    ; DR4 is alias to DR6 only if DE (in CR4) is cleared. Otherwise, reading\r
+    ; this register will cause a #UD exception.\r
+    ;\r
+    ; MS assembler doesn't support this instruction since no one would use it\r
+    ; under normal circustances. Here opcode is used.\r
+    ;\r
     DB      0fh, 21h, 0e0h\r
     ret\r
 AsmReadDr4  ENDP\r
index bba8b60..091792d 100644 (file)
 ;   );\r
 ;------------------------------------------------------------------------------\r
 AsmReadDr5  PROC\r
+    ;\r
+    ; DR5 is alias to DR7 only if DE (in CR4) is cleared. Otherwise, reading\r
+    ; this register will cause a #UD exception.\r
+    ;\r
+    ; MS assembler doesn't support this instruction since no one would use it\r
+    ; under normal circustances. Here opcode is used.\r
+    ;\r
     DB      0fh, 21h, 0e8h\r
     ret\r
 AsmReadDr5  ENDP\r
index 4d745e2..4b7b40c 100644 (file)
@@ -34,16 +34,16 @@ InternalAssertJumpBuffer    PROTO   C
 ;------------------------------------------------------------------------------\r
 SetJump     PROC\r
     push    [esp + 4]\r
-    call    InternalAssertJumpBuffer\r
-    pop     ecx\r
+    call    InternalAssertJumpBuffer    ; To validate JumpBuffer\r
     pop     ecx\r
+    pop     ecx                         ; ecx <- return address\r
     mov     edx, [esp]\r
     mov     [edx], ebx\r
     mov     [edx + 4], esi\r
     mov     [edx + 8], edi\r
     mov     [edx + 12], ebp\r
     mov     [edx + 16], esp\r
-    mov     [edx + 20], ecx\r
+    mov     [edx + 20], ecx             ; eip value to restore in LongJump\r
     xor     eax, eax\r
     jmp     ecx\r
 SetJump     ENDP\r
index 186d094..7647880 100644 (file)
@@ -33,8 +33,8 @@
 ;   );\r
 ;------------------------------------------------------------------------------\r
 InternalMathSwapBytes64 PROC\r
-    mov     eax, [esp + 8]\r
-    mov     edx, [esp + 4]\r
+    mov     eax, [esp + 8]              ; eax <- upper 32 bits\r
+    mov     edx, [esp + 4]              ; edx <- lower 32 bits\r
     bswap   eax\r
     bswap   edx\r
     ret\r
index 5e35799..5c9bc81 100644 (file)
@@ -75,6 +75,11 @@ SavedGdt    LABEL   FWORD
 ; by user code. It will be shadowed to somewhere in memory below 1MB.\r
 ;------------------------------------------------------------------------------\r
 _BackFromUserCode   PROC\r
+    ;\r
+    ; The order of saved registers on the stack matches the order they appears\r
+    ; in IA32_REGS structure. This facilitates wrapper function to extract them\r
+    ; into that structure.\r
+    ;\r
     push    ss\r
     push    cs\r
     DB      66h\r
@@ -104,6 +109,11 @@ _ThunkAttr  DD      ?
     mov     eax, ss\r
     DB      67h\r
     lea     bp, [esp + sizeof (IA32_REGS)]\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     word ptr (IA32_REGS ptr [esi - sizeof (IA32_REGS)])._ESP, bp\r
     mov     ebx, (IA32_REGS ptr [esi - sizeof (IA32_REGS)])._EIP\r
     shl     ax, 4                       ; shl eax, 4\r
@@ -167,7 +177,7 @@ _ToUserCode PROC
     pop     fs\r
     pop     gs\r
     popf                                ; popfd\r
-    DB      66h\r
+    DB      66h                         ; Use 32-bit addressing for "retf" below\r
     retf                                ; transfer control to user code\r
 _ToUserCode ENDP\r
 \r
@@ -197,7 +207,7 @@ GdtEnd          LABEL   QWORD
 ;   );\r
 ;------------------------------------------------------------------------------\r
 InternalAsmThunk16  PROC    USES    ebp ebx esi edi ds  es  fs  gs\r
-    mov     esi, [esp + 36]             ; esi <- RegSet\r
+    mov     esi, [esp + 36]             ; esi <- RegSet, the 1st parameter\r
     movzx   edx, (IA32_REGS ptr [esi])._SS\r
     mov     edi, (IA32_REGS ptr [esi])._ESP\r
     add     edi, - (sizeof (IA32_REGS) + 4) ; reserve stack space\r
@@ -227,11 +237,11 @@ InternalAsmThunk16  PROC    USES    ebp ebx esi edi ds  es  fs  gs
     push    10h\r
     pop     ecx                         ; ecx <- selector for data segments\r
     lgdt    fword ptr [edx + (_16Gdtr - SavedCr0)]\r
-    pushfd\r
+    pushfd                              ; Save df/if indeed\r
     call    fword ptr [edx + (_EntryPoint - SavedCr0)]\r
     popfd\r
     lidt    fword ptr [esp + 36]        ; restore protected mode IDTR\r
-    lea     eax, [ebp - sizeof (IA32_REGS)]\r
+    lea     eax, [ebp - sizeof (IA32_REGS)] ; eax <- the address of IA32_REGS\r
     ret\r
 InternalAsmThunk16  ENDP\r
 \r
index ca9a839..9c10305 100644 (file)
 ;------------------------------------------------------------------------------\r
 AsmWriteDr4 PROC\r
     mov     eax, [esp + 4]\r
+    ;\r
+    ; DR4 is alias to DR6 only if DE (in CR4) is cleared. Otherwise, writing to\r
+    ; this register will cause a #UD exception.\r
+    ;\r
+    ; MS assembler doesn't support this instruction since no one would use it\r
+    ; under normal circustances. Here opcode is used.\r
+    ;\r
     DB      0fh, 23h, 0e0h\r
     ret\r
 AsmWriteDr4 ENDP\r
index c6def68..e10434e 100644 (file)
 ;------------------------------------------------------------------------------\r
 AsmWriteDr5 PROC\r
     mov     eax, [esp + 4]\r
+    ;\r
+    ; DR5 is alias to DR7 only if DE (in CR4) is cleared. Otherwise, writing to\r
+    ; this register will cause a #UD exception.\r
+    ;\r
+    ; MS assembler doesn't support this instruction since no one would use it\r
+    ; under normal circustances. Here opcode is used.\r
+    ;\r
     DB      0fh, 23h, 0e8h\r
     ret\r
 AsmWriteDr5 ENDP\r
index 2609c94..518137d 100644 (file)
 ;------------------------------------------------------------------------------\r
 InternalX86DisablePaging64    PROC\r
     cli\r
-    shl     rcx, 32\r
+    shl     rcx, 32                     ; rcx[32..47] <- Cs\r
     lea     eax, @F\r
-    mov     ecx, eax\r
-    push    rcx\r
-    mov     ebx, edx\r
     mov     esi, r8d\r
+    or      rcx, rax                    ; rcx[0..47] <- Cs:@F\r
     mov     edi, r9d\r
-    mov     eax, [rsp + 28h]\r
-    retf\r
+    mov     eax, [rsp + 28h]            ; eax <- New Stack\r
+    push    rcx\r
+    retf                                ; switch to compatibility mode\r
 @@:\r
     mov     esp, eax                    ; set up new stack\r
     mov     rax, cr0\r
@@ -57,10 +56,10 @@ InternalX86DisablePaging64    PROC
     mov     rax, cr4\r
     and     al, NOT (1 SHL 5)           ; clear PAE\r
     mov     cr4, rax\r
-    push    rdi\r
-    push    rsi\r
-    call    rbx\r
-    jmp     $\r
+    push    rdi                         ; push Context2\r
+    push    rsi                         ; push Context1\r
+    call    rdx                         ; transfer control to EntryPoint\r
+    hlt                                 ; no one should get here\r
 InternalX86DisablePaging64    ENDP\r
 \r
     END\r
index 459120a..c548430 100644 (file)
@@ -36,7 +36,7 @@
 ;------------------------------------------------------------------------------\r
 InternalX86EnablePaging64 PROC\r
     cli\r
-    pop     rax\r
+    pop     rax                         ; skip the return address\r
     call    @Base\r
 @Base:\r
     add     dword ptr [rsp], @F - @Base ; offset for far retf, seg is the 1st arg\r
@@ -58,7 +58,7 @@ InternalX86EnablePaging64 PROC
     mov     rsp, [esp + 18h]\r
     add     rsp, -20h\r
     call    rbx\r
-    jmp     $                           ; halt processor if EntryPoint() returned\r
+    hlt                                 ; halt processor if EntryPoint() returned\r
 InternalX86EnablePaging64 ENDP\r
 \r
     END\r
index 6ef5f96..38e5606 100644 (file)
@@ -39,7 +39,7 @@ InternalLongJump    PROC
     mov     r13, [rcx + 30h]\r
     mov     r14, [rcx + 38h]\r
     mov     r15, [rcx + 40h]\r
-    mov     rax, rdx\r
+    mov     rax, rdx                    ; set return value\r
     jmp     qword ptr [rcx + 48h]\r
 InternalLongJump    ENDP\r
 \r
index 0140494..ec9c3f8 100644 (file)
@@ -36,7 +36,7 @@ AsmMonitor  PROC
     mov     eax, ecx\r
     mov     ecx, edx\r
     mov     edx, r8d\r
-    DB      0fh, 1, 0c8h\r
+    DB      0fh, 1, 0c8h                ; monitor\r
     ret\r
 AsmMonitor  ENDP\r
 \r
index 8f76d94..aae1d42 100644 (file)
@@ -34,7 +34,7 @@
 AsmMwait    PROC\r
     mov     eax, ecx\r
     mov     ecx, edx\r
-    DB      0fh, 1, 0c9h\r
+    DB      0fh, 1, 0c9h                ; mwait\r
     ret\r
 AsmMwait    ENDP\r
 \r
index 9774001..2bed129 100644 (file)
 ;   );\r
 ;------------------------------------------------------------------------------\r
 AsmReadDr4  PROC\r
+    ;\r
+    ; There's no obvious reason to access this register, since it's aliased to\r
+    ; DR7 when DE=0 or an exception generated when DE=1\r
+    ;\r
     DB      0fh, 21h, 0e0h\r
     ret\r
 AsmReadDr4  ENDP\r
index 0582502..3bee3a5 100644 (file)
 ;   );\r
 ;------------------------------------------------------------------------------\r
 AsmReadDr5  PROC\r
+    ;\r
+    ; There's no obvious reason to access this register, since it's aliased to\r
+    ; DR7 when DE=0 or an exception generated when DE=1\r
+    ;\r
     DB      0fh, 21h, 0e8h\r
     ret\r
 AsmReadDr5  ENDP\r
index a81d208..0ed5c8f 100644 (file)
@@ -31,6 +31,9 @@
 ;   );\r
 ;------------------------------------------------------------------------------\r
 AsmReadMm0  PROC\r
+    ;\r
+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here\r
+    ;\r
     DB      48h, 0fh, 7eh, 0c0h\r
     ret\r
 AsmReadMm0  ENDP\r
index 5da8c4f..e24fcb5 100644 (file)
@@ -31,6 +31,9 @@
 ;   );\r
 ;------------------------------------------------------------------------------\r
 AsmReadMm1  PROC\r
+    ;\r
+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here\r
+    ;\r
     DB      48h, 0fh, 7eh, 0c8h\r
     ret\r
 AsmReadMm1  ENDP\r
index 3b2b1e3..860326b 100644 (file)
@@ -31,6 +31,9 @@
 ;   );\r
 ;------------------------------------------------------------------------------\r
 AsmReadMm2  PROC\r
+    ;\r
+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here\r
+    ;\r
     DB      48h, 0fh, 7eh, 0d0h\r
     ret\r
 AsmReadMm2  ENDP\r
index 6283c30..aca6f3d 100644 (file)
@@ -31,6 +31,9 @@
 ;   );\r
 ;------------------------------------------------------------------------------\r
 AsmReadMm3  PROC\r
+    ;\r
+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here\r
+    ;\r
     DB      48h, 0fh, 7eh, 0d8h\r
     ret\r
 AsmReadMm3  ENDP\r
index a65f130..dd52f99 100644 (file)
@@ -31,6 +31,9 @@
 ;   );\r
 ;------------------------------------------------------------------------------\r
 AsmReadMm4  PROC\r
+    ;\r
+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here\r
+    ;\r
     DB      48h, 0fh, 7eh, 0e0h\r
     ret\r
 AsmReadMm4  ENDP\r
index 5295c38..1f30e4b 100644 (file)
@@ -31,6 +31,9 @@
 ;   );\r
 ;------------------------------------------------------------------------------\r
 AsmReadMm5  PROC\r
+    ;\r
+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here\r
+    ;\r
     DB      48h, 0fh, 7eh, 0e8h\r
     ret\r
 AsmReadMm5  ENDP\r
index acdc99b..4e1f2a8 100644 (file)
@@ -31,6 +31,9 @@
 ;   );\r
 ;------------------------------------------------------------------------------\r
 AsmReadMm6  PROC\r
+    ;\r
+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here\r
+    ;\r
     DB      48h, 0fh, 7eh, 0f0h\r
     ret\r
 AsmReadMm6  ENDP\r
index 7a1b4e6..d871a9f 100644 (file)
@@ -31,6 +31,9 @@
 ;   );\r
 ;------------------------------------------------------------------------------\r
 AsmReadMm7  PROC\r
+    ;\r
+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here\r
+    ;\r
     DB      48h, 0fh, 7eh, 0f8h\r
     ret\r
 AsmReadMm7  ENDP\r
index 6423108..556a8b4 100644 (file)
@@ -66,6 +66,14 @@ SavedGdt    LABEL   FWORD
 ; by user code. It will be shadowed to somewhere in memory below 1MB.\r
 ;------------------------------------------------------------------------------\r
 _BackFromUserCode   PROC\r
+    ;\r
+    ; The order of saved registers on the stack matches the order they appears\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
@@ -115,7 +123,7 @@ SavedCr4    DD      ?
     ;\r
     ; rdi in the instruction below is indeed bx in 16-bit code\r
     ;\r
-    DB      66h, 2eh\r
+    DB      66h, 2eh                    ; 2eh is "cs:" segment override\r
     lgdt    fword ptr [rdi + (SavedGdt - @Base)]\r
     DB      66h\r
     mov     ecx, 0c0000080h\r
@@ -129,9 +137,8 @@ SavedCr0    DD      ?
 @64Eip      DD      ?\r
 SavedCs     DW      ?\r
 @64BitCode:\r
-    DB      48h, 0b8h                   ; mov rax, imm64\r
-SavedRip    DQ      ?\r
-    jmp     rax                         ; return to caller\r
+    mov     rsp, r8                     ; restore stack\r
+    ret\r
 _BackFromUserCode   ENDP\r
 \r
 _EntryPoint DD      _ToUserCode - m16Start\r
@@ -160,14 +167,14 @@ _ToUserCode PROC
     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\r
+    DB      66h                         ; make the following call 32-bit\r
     call    @Base                       ; push eip\r
 @Base:\r
     pop     bp                          ; ebp <- address of @Base\r
     push    [esp + sizeof (IA32_REGS) + 2]\r
-    lea     eax, [rsi + (@RealMode - @Base)]\r
+    lea     eax, [rsi + (@RealMode - @Base)]    ; rsi is "bp" in 16-bit code\r
     push    rax\r
-    retf\r
+    retf                                ; execution begins at next instruction\r
 @RealMode:\r
     DB      66h, 2eh                    ; CS and operand size override\r
     lidt    fword ptr [rsi + (_16Idtr - @Base)]\r
@@ -178,7 +185,7 @@ _ToUserCode PROC
     pop     gs\r
     popf                                ; popfd\r
     lea     sp, [esp + 4]               ; skip high order 32 bits of EFlags\r
-    DB      66h\r
+    DB      66h                         ; make the following retf 32-bit\r
     retf                                ; transfer control to user code\r
 _ToUserCode ENDP\r
 \r
@@ -220,8 +227,8 @@ GDT_SIZE = $ - _NullSeg
 ;   );\r
 ;------------------------------------------------------------------------------\r
 InternalAsmThunk16  PROC    USES    rbp rbx rsi rdi\r
-    mov     r10d, ds\r
-    mov     r11d, es\r
+    mov     r10d, ds                    ; r9 ~ r11 are not accessible in 16-bit\r
+    mov     r11d, es                    ; so use them for saving seg registers\r
     mov     r9d, ss\r
     push    fs\r
     push    gs\r
@@ -238,8 +245,8 @@ InternalAsmThunk16  PROC    USES    rbp rbx rsi rdi
     lea     ecx, [rdx + (SavedCr4 - m16Start)]\r
     mov     eax, edx                    ; eax <- transition code address\r
     and     edx, 0fh\r
-    shl     eax, 12\r
-    lea     ax, [rdx + (_BackFromUserCode - m16Start)]\r
+    shl     eax, 12                     ; segment address in high order 16 bits\r
+    lea     ax, [rdx + (_BackFromUserCode - m16Start)]  ; offset address\r
     stosd                               ; [edi] <- return address of user code\r
     sgdt    fword ptr [rcx + (SavedGdt - SavedCr4)]\r
     sidt    fword ptr [rsp + 38h]       ; save IDT stack in argument space\r
@@ -257,13 +264,12 @@ InternalAsmThunk16  PROC    USES    rbp rbx rsi rdi
     pushfq\r
     lea     edx, [rdx + DATA16 - DATA32]\r
     lea     r8, @RetFromRealMode\r
-    mov     [rcx + (SavedRip - SavedCr4)], r8\r
+    push    r8\r
     mov     r8d, cs\r
     mov     [rcx + (SavedCs - SavedCr4)], r8w\r
     mov     r8, rsp\r
     jmp     fword ptr [rcx + (_EntryPoint - SavedCr4)]\r
 @RetFromRealMode:\r
-    mov     rsp, r8\r
     popfq\r
     lidt    fword ptr [rsp + 38h]       ; restore protected mode IDTR\r
     lea     eax, [rbp - sizeof (IA32_REGS)]\r
index ad618f1..188a9d4 100644 (file)
 ;   );\r
 ;------------------------------------------------------------------------------\r
 AsmWriteDr4 PROC\r
+    ;\r
+    ; There's no obvious reason to access this register, since it's aliased to\r
+    ; DR6 when DE=0 or an exception generated when DE=1\r
+    ;\r
     DB      0fh, 23h, 0e1h\r
     mov     rax, rcx\r
     ret\r
index 91eeef2..86009c3 100644 (file)
 ;   );\r
 ;------------------------------------------------------------------------------\r
 AsmWriteDr5 PROC\r
+    ;\r
+    ; There's no obvious reason to access this register, since it's aliased to\r
+    ; DR7 when DE=0 or an exception generated when DE=1\r
+    ;\r
     DB      0fh, 23h, 0e9h\r
     mov     rax, rcx\r
     ret\r
index 0ad65e3..7496362 100644 (file)
@@ -31,6 +31,9 @@
 ;   );\r
 ;------------------------------------------------------------------------------\r
 AsmWriteMm0 PROC\r
+    ;\r
+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here\r
+    ;\r
     DB      48h, 0fh, 6eh, 0c1h\r
     ret\r
 AsmWriteMm0 ENDP\r
index 66425a4..a00f551 100644 (file)
@@ -31,6 +31,9 @@
 ;   );\r
 ;------------------------------------------------------------------------------\r
 AsmWriteMm1 PROC\r
+    ;\r
+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here\r
+    ;\r
     DB      48h, 0fh, 6eh, 0c9h\r
     ret\r
 AsmWriteMm1 ENDP\r
index bd0f0a0..01db790 100644 (file)
@@ -31,6 +31,9 @@
 ;   );\r
 ;------------------------------------------------------------------------------\r
 AsmWriteMm2 PROC\r
+    ;\r
+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here\r
+    ;\r
     DB      48h, 0fh, 6eh, 0d1h\r
     ret\r
 AsmWriteMm2 ENDP\r
index fa36ea6..5946464 100644 (file)
@@ -31,6 +31,9 @@
 ;   );\r
 ;------------------------------------------------------------------------------\r
 AsmWriteMm3 PROC\r
+    ;\r
+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here\r
+    ;\r
     DB      48h, 0fh, 6eh, 0d9h\r
     ret\r
 AsmWriteMm3 ENDP\r
index d9bc46e..6848dbf 100644 (file)
@@ -31,6 +31,9 @@
 ;   );\r
 ;------------------------------------------------------------------------------\r
 AsmWriteMm4 PROC\r
+    ;\r
+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here\r
+    ;\r
     DB      48h, 0fh, 6eh, 0e1h\r
     ret\r
 AsmWriteMm4 ENDP\r
index f268bea..fbe44ae 100644 (file)
@@ -31,6 +31,9 @@
 ;   );\r
 ;------------------------------------------------------------------------------\r
 AsmWriteMm5 PROC\r
+    ;\r
+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here\r
+    ;\r
     DB      48h, 0fh, 6eh, 0e9h\r
     ret\r
 AsmWriteMm5 ENDP\r
index cb32ea6..cd59388 100644 (file)
@@ -31,6 +31,9 @@
 ;   );\r
 ;------------------------------------------------------------------------------\r
 AsmWriteMm6 PROC\r
+    ;\r
+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here\r
+    ;\r
     DB      48h, 0fh, 6eh, 0f1h\r
     ret\r
 AsmWriteMm6 ENDP\r
index f571382..9636a4c 100644 (file)
@@ -31,6 +31,9 @@
 ;   );\r
 ;------------------------------------------------------------------------------\r
 AsmWriteMm7 PROC\r
+    ;\r
+    ; 64-bit MASM doesn't support MMX instructions, so use opcode here\r
+    ;\r
     DB      48h, 0fh, 6eh, 0f9h\r
     ret\r
 AsmWriteMm7 ENDP\r
index 6b8066f..b7704b8 100644 (file)
@@ -32,8 +32,8 @@
 ;   );\r
 ;------------------------------------------------------------------------------\r
 AsmWriteMsr64   PROC\r
-    mov     rax, rdx\r
-    shr     rdx, 20h\r
+    mov     rax, rdx                    ; meanwhile, rax <- return value\r
+    shr     rdx, 20h                    ; edx:eax contains the value to write\r
     wrmsr\r
     ret\r
 AsmWriteMsr64   ENDP\r