singrdk/base/Kernel/Native/ring3_halstack.asm

127 lines
4.7 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-3 application code. This code is
;; used to satisfy ring-3 applications' import of the LinkStack and
;; UnlinkStack symbols.
;;
.686p
.mmx
.xmm
.model flat
.code
assume ds:flat
assume es:flat
assume ss:flat
assume fs:nothing
assume gs:nothing
include hal.inc
;;; Public symbols
public ?g_LinkStack@Struct_Microsoft_Singularity_V1_Services_StackService@@SIXXZ
public ?g_UnlinkStack@Struct_Microsoft_Singularity_V1_Services_StackService@@SIXXZ
;;; Ring-3-specific stack ABIs
externdef ?g_LinkNewStackSegment@Struct_Microsoft_Singularity_V1_Services_StackService@@SIPAUuintPtr@@PAU2@PAII000@Z:NEAR
externdef ?g_ReturnStackSegmentRaw@Struct_Microsoft_Singularity_V1_Services_StackService@@SIXPAUuintPtr@@0@Z:NEAR
align 16
;;; Stack:
;;; arg2.. (args 0 & 1 = ECX & EDX) + 40
;;; caller (addr) + 36
;;; caller ebp + 32 <= old EBP
;;; callee (addr) + 28 <= old ESP
;;; argsize + 24
;;; unlinkN + 20
;;; eax + 16
;;; ecx + 12
;;; edx + 8
;;; stackLimit + 4
;;; stackBegin + 0
?g_LinkStack@Struct_Microsoft_Singularity_V1_Services_StackService@@SIXXZ::
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
;; Save the old ESP (and create a temporary frame head).
lea ecx,[eax+28]
push ecx
;; Call LinkNewStackSegment(ecx=stack needed, edx=*args, args,
;; esp, begin, limit)
push [eax+4] ; stackLimit on old stack
push [eax+0] ; stackBegin on old stack
push ecx ; old esp
push [eax+24] ; #args
lea edx,[eax+40] ; &arg2
mov ecx,[eax+16] ; stack size needed
call ?g_LinkNewStackSegment@Struct_Microsoft_Singularity_V1_Services_StackService@@SIPAUuintPtr@@PAU2@PAII000@Z
;; Get back to old ESP, then adjust to pop off EDX and ECX
pop ecx
sub ecx,28
mov esp,eax
push [ecx+20] ; unlinkN
mov eax,[ecx+28] ; callee
mov edx,[ecx+8] ; edx
mov ecx,[ecx+12] ; ecx
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::
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
;;; Stack:
;;; caller (addr) + 12
;;; caller ebp + 8
;;; eax + 4
;;; edx + 0
;; Call ReturnStackSegmentRaw(ecx=begin, edx=limit)
mov eax,fs:[Struct_Microsoft_Singularity_X86_ProcessorContext._threadContext]
mov edx,[eax].Struct_Microsoft_Singularity_X86_ThreadContext._stackLimit
mov ecx,[eax].Struct_Microsoft_Singularity_X86_ThreadContext._stackBegin
call ?g_ReturnStackSegmentRaw@Struct_Microsoft_Singularity_V1_Services_StackService@@SIXPAUuintPtr@@0@Z
pop edx ; restore eax and edx
pop eax
pop ebp ; pop ebp chain
ret
end