windows-nt/Source/XPSP1/NT/base/boot/startup/i386/macro.inc
2020-09-26 16:20:57 +08:00

239 lines
5.5 KiB
PHP
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;++
;
; File Name:
;
; macro.inc
;
; Author:
;
; Thomas Parslow [tomp]
;
; Created:
;
; 27-Feb-91
;
; Abstract:
;
; The macros used for creating the exported entry points the
; OS loader will use for basic h/w dependent services. These
; services are:
;
; o Disk I/O
; o Character I/O
;
;
;--
;++
;
; EXPORT_ENTRY_MACRO
; We arrive here from the OS loader with a 32bit CS. That is, we're
; executing the code with cs:eip where cs contains a selector for a
; 32bit flat segment. We want to get to a 16bit cs. That is, cs:ip.
; The entry points are exported as 32bit near pointers to the OS loader.
; All code in the SU module is identity mapped so the flat 32bit offset
; is equal to the physical address.
;
; Therefore, we export the 32bit physical address as the
; entry point and the code may be executed with either the 32bit
; flat cs or the SU module's 16bit based cs. Before we can switch
; modes we must load all of the segment registers with selectors for
; 16bit segments. We start by pushing a far pointer to a label in
; the macro and then doing a retf. This allows us to fall through
; to the next instruction, but we're now executing through cs:ip
; with a 16bit CS.
;
; Output:
;
; (ebx) = pointer to stack frame (and top of 32bit stack).
;
EXPORT_ENTRY_MACRO macro entryname
LOCAL exp1
_TEXT32 segment para use32 public 'CODE'
ASSUME CS:_TEXT32
ALIGN 4
Public EntryName
EntryName LABEL near
;
; We've go a 32bit CS:EIP - go to a 16bit CS:IP
push dword ptr SuCodeSelector
push dword ptr (offset exp1)
retf
_TEXT32 ends
ASSUME CS:_TEXT
ALIGN 4
exp1:
;
; Save caller's EBP register and stack pointer (ESP)
;
push ebp
push ebx
push esi
push edi
mov ebx,esp
;
; Load all the segment registers with 16bit segment selectors
;
mov ax,SuDataSelector
mov ds,ax
mov ss,ax
;
; Set the stack to the top of the segment. We can do this now since
; all of the OS loader's code has already be relocated. Also, we need
; plenty of stack since we'll be calling BIOS routines.
;
mov sp,EXPORT_STACK
push ebx ; save the caller's esp
endm
;
; EXPORT_ENTRY_MACRO end
;
;++
;
; Name:
;
; ExportExit
;
; Arguments:
;
;
; Notes:
;
; EAX = return code and MUST be preserved by this macro.
;
;--
EXPORT_EXIT_MACRO macro
;
; Next get caller's esp that we saved upon entry on the 16bit stack
;
pop ebx ; get caller's esp
;
; Restore flat selectors in segment registers.
;
mov dx,KeDataSelector
mov ds,dx
mov ss,dx
mov es,dx
mov esp,ebx
;
; Restore callers' ebp that we saved on the 32bit stack
;
pop edi
pop esi
pop ebx
pop ebp ; (ebp) = caller's ebp
;
; Pull callers flat return address off stack and push the
; flat code selector followed by the return offset, then
; execute a far return and we'll be back in the OS loaders code space.
;
pop edx ; (edx) = caller's return address
push dword ptr KeCodeSelector
push edx
db OVERRIDE
retf
endm
;++
;
;
;
;--
RE_ENABLE_PAGING_MACRO macro
extrn _EnableProtectPaging:near
push RE_ENABLING
call _EnableProtectPaging
add sp,2
endm
ENTER_REALMODE_MACRO macro
extrn _RealMode:near
call _RealMode
endm
WAIT_FOREVER_MACRO macro
LOCAL wf1
wf1: jmp wf1
endm
;++
;
; MAKE_STACK_FRAME_MACRO
;
; Arguments:
;
; _FrameName_ - is the name of the structure defining the
; stack frame layout.
;
; _PointerRegister_ - is the register containing the linear pointer to
; the top of the stack frame.
; ProtectMode ONLY
;
;--
MAKE_STACK_FRAME_MACRO macro _FrameName_ , _PointerRegister_
Local msf1
mov ecx, (size _FrameName_)/2
mov esi,_PointerRegister_ ; (esi) = offset of argument frame
add esi,20 ; account for ebp, ebx, esi, edi and
; return address
push KeDataSelector ; (ax) = Flat 32bit segment selector
pop ds ; (ds:esi) points to argument frame
push ss ;
pop es ; (es) = 16bit stack selector
sub sp, size _FrameName_ ; make room for the arguments
xor edi,edi ; clear out upper 16bits of edi
mov di,sp ; (es:edi) points to top of stack
msf1:
mov ax,[esi]
mov es:[edi],ax
add esi,2
add edi,2
loop msf1
push es ;
pop ds ; put 16bit selector back into ds
endm
REMOVE_STACK_FRAME_MACRO macro _FrameName_
add sp, size _FrameName_
endm
;BuildDescriptor macro Base,Limit,Access,Dpl,Stype
; dw (Limit AND 0ffffh)
; dw (Base AND 0ffffh)
; db ((Base SHR 16) AND 0ffh)
; db (Gran + Dpl + Stype)
; db ((Limit SHR 16) AND 0ffh)
; db ((Base SHR 24) AND 0ffh)
; endm
;
;
;
RETURNCODE_IN_EAX_MACRO macro
shl edx,16
mov dx,ax
mov eax,edx
endm