181 lines
7.0 KiB
NASM
181 lines
7.0 KiB
NASM
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
;;
|
||
|
;; Microsoft Research Singularity
|
||
|
;;
|
||
|
;; Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
;;
|
||
|
;; File: halstack.asm
|
||
|
;;
|
||
|
;; Note:
|
||
|
;; This file contains implementations of the LinkStack and UnlinkStack
|
||
|
;; routines suitable for use by ring-0 code (kernel and ring-0 apps).
|
||
|
;;
|
||
|
|
||
|
.686p
|
||
|
.mmx
|
||
|
.xmm
|
||
|
.model flat
|
||
|
.code
|
||
|
|
||
|
ifdef SINGULARITY
|
||
|
assume ds:flat
|
||
|
assume es:flat
|
||
|
assume ss:flat
|
||
|
assume fs:nothing
|
||
|
assume gs:nothing
|
||
|
else ; Singularity
|
||
|
PAGE_BITS EQU 12
|
||
|
endif ; Singularity
|
||
|
|
||
|
include hal.inc
|
||
|
|
||
|
align 16
|
||
|
|
||
|
;; Public symbols
|
||
|
public ?g_LinkStack@Struct_Microsoft_Singularity_V1_Services_StackService@@SIXXZ
|
||
|
public ?g_UnlinkStack@Struct_Microsoft_Singularity_V1_Services_StackService@@SIXXZ
|
||
|
|
||
|
;;; Stack:
|
||
|
;;; arg2.. (args 0 & 1 = ECX & EDX) + 44
|
||
|
;;; caller (addr) + 40
|
||
|
;;; caller ebp + 36 <= old EBP
|
||
|
;;; callee (addr) + 32 <= old ESP
|
||
|
;;; argsize + 28
|
||
|
;;; unlinkN + 24
|
||
|
;;; efl + 20
|
||
|
;;; eax + 16
|
||
|
;;; ecx + 12
|
||
|
;;; edx + 8
|
||
|
;;; stackLimit + 4
|
||
|
;;; stackBegin + 0
|
||
|
?g_LinkStack@Struct_Microsoft_Singularity_V1_Services_StackService@@SIXXZ ::
|
||
|
|
||
|
;; Disable interrupts
|
||
|
pushfd ; +20
|
||
|
cli
|
||
|
push eax ; +16
|
||
|
push ecx ; +12
|
||
|
push edx ; +8
|
||
|
|
||
|
mov edx,fs:[Struct_Microsoft_Singularity_X86_ProcessorContext._threadContext]
|
||
|
push [edx].Struct_Microsoft_Singularity_X86_ThreadContext._stackLimit ; +4
|
||
|
push [edx].Struct_Microsoft_Singularity_X86_ThreadContext._stackBegin ; +0
|
||
|
|
||
|
mov eax,esp
|
||
|
|
||
|
;; Change to schedulerStack
|
||
|
mov ecx,fs:[Struct_Microsoft_Singularity_X86_ProcessorContext._schedulerStackLimit]
|
||
|
mov [edx].Struct_Microsoft_Singularity_X86_ThreadContext._stackLimit,ecx
|
||
|
mov ecx,fs:[Struct_Microsoft_Singularity_X86_ProcessorContext._schedulerStackBegin]
|
||
|
mov [edx].Struct_Microsoft_Singularity_X86_ThreadContext._stackBegin,ecx
|
||
|
|
||
|
ifdef DEBUG
|
||
|
;; If we're already on the scheduler stack, we're in trouble,
|
||
|
;; so trap to the debugger:
|
||
|
cmp eax, [edx].Struct_Microsoft_Singularity_X86_ThreadContext._stackBegin
|
||
|
jg stackOk
|
||
|
cmp eax, [edx].Struct_Microsoft_Singularity_X86_ThreadContext._stackLimit
|
||
|
jl stackOk
|
||
|
sti
|
||
|
int 3
|
||
|
stackOk:
|
||
|
endif ;; DEBUG
|
||
|
|
||
|
mov esp,ecx
|
||
|
|
||
|
;; Save the old ESP (and create a temporary frame head).
|
||
|
lea ecx,[eax+32]
|
||
|
push ecx
|
||
|
push [eax+4] ; stackLimit on old stack
|
||
|
push [eax+0] ; stackBegin on old stack
|
||
|
|
||
|
;; Call GetStackSegmentAndCopy(ecx=stack needed, edx=threadContext, *args, args,
|
||
|
;; esp, begin, limit)
|
||
|
push ecx ; old esp
|
||
|
push [eax+28] ; #args
|
||
|
lea ecx,[eax+44] ; &arg2
|
||
|
push ecx ;
|
||
|
mov ecx,[eax+16] ; stack size needed
|
||
|
|
||
|
call ?g_GetStackSegmentAndCopy@Class_Microsoft_Singularity_Memory_Stacks@@SIPAUuintPtr@@PAU2@PAUStruct_Microsoft_Singularity_X86_ThreadContext@@PAII000@Z
|
||
|
|
||
|
;; Get back to old ESP, then adjust to pop off EDX and ECX
|
||
|
pop ecx
|
||
|
sub ecx,32
|
||
|
mov esp,eax
|
||
|
|
||
|
push [ecx+24] ; unlinkN
|
||
|
push [ecx+20] ; efl
|
||
|
mov eax,[ecx+32] ; callee
|
||
|
mov edx,[ecx+8] ; edx
|
||
|
mov ecx,[ecx+12] ; ecx
|
||
|
|
||
|
;; Restore interrupts
|
||
|
popfd
|
||
|
|
||
|
push ebp ; Create new ebp frame.
|
||
|
mov ebp,esp
|
||
|
jmp eax ; jump to callee code.
|
||
|
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
;; NB: See halstack.asm for a stack diagram
|
||
|
|
||
|
?g_UnlinkStack@Struct_Microsoft_Singularity_V1_Services_StackService@@SIXXZ::
|
||
|
|
||
|
;; Disable interrupts and remove dead args from old stack
|
||
|
pushfd
|
||
|
cli
|
||
|
|
||
|
mov esp,ebp ; Find adjusted ebp
|
||
|
add esp,ecx
|
||
|
mov ecx,[ebp+4] ; move eip link up
|
||
|
mov [esp+4],ecx
|
||
|
mov ecx,[ebp+0] ; move ebp link up
|
||
|
mov [esp+0],ecx
|
||
|
mov ebp,esp
|
||
|
|
||
|
push eax ; save eax to old stack
|
||
|
push edx ; save edx to old stack
|
||
|
|
||
|
mov ecx,fs:[Struct_Microsoft_Singularity_X86_ProcessorContext._threadContext]
|
||
|
mov eax,[ecx].Struct_Microsoft_Singularity_X86_ThreadContext._stackBegin
|
||
|
mov eax,[eax-16] ; save efl to old stack
|
||
|
push eax
|
||
|
|
||
|
;;; Stack:
|
||
|
;;; caller (addr) + 16
|
||
|
;;; caller ebp + 12
|
||
|
;;; eax + 8
|
||
|
;;; edx + 4
|
||
|
;;; efl + 0
|
||
|
|
||
|
;; Prepare scheduler stack segment.
|
||
|
mov eax,esp
|
||
|
mov esp,fs:[Struct_Microsoft_Singularity_X86_ProcessorContext._schedulerStackBegin]
|
||
|
push eax ; save old esp
|
||
|
push [ecx].Struct_Microsoft_Singularity_X86_ThreadContext._stackBegin
|
||
|
push [ecx].Struct_Microsoft_Singularity_X86_ThreadContext._stackLimit
|
||
|
|
||
|
push [ecx].Struct_Microsoft_Singularity_X86_ThreadContext._stackLimit
|
||
|
mov edx,[ecx].Struct_Microsoft_Singularity_X86_ThreadContext._stackBegin
|
||
|
|
||
|
;; Then switch to scheduler stack.
|
||
|
mov eax,fs:[Struct_Microsoft_Singularity_X86_ProcessorContext._schedulerStackLimit]
|
||
|
mov [ecx].Struct_Microsoft_Singularity_X86_ThreadContext._stackLimit,eax
|
||
|
mov eax,fs:[Struct_Microsoft_Singularity_X86_ProcessorContext._schedulerStackBegin]
|
||
|
mov [ecx].Struct_Microsoft_Singularity_X86_ThreadContext._stackBegin,eax
|
||
|
|
||
|
;; Call ReturnStackSegmentRaw(ecx=threadContext, edx=begin, limit)
|
||
|
call ?g_ReturnStackSegmentRaw@Class_Microsoft_Singularity_Memory_Stacks@@SIXPAUStruct_Microsoft_Singularity_X86_ThreadContext@@PAUuintPtr@@1@Z
|
||
|
|
||
|
pop eax ; pop old limit
|
||
|
pop eax ; pop old begin
|
||
|
pop esp ; restore esp
|
||
|
popfd ; restore interrupts
|
||
|
pop edx ; restore eax and edx
|
||
|
pop eax
|
||
|
pop ebp ; pop ebp chain
|
||
|
ret
|
||
|
|
||
|
end
|