127 lines
4.7 KiB
NASM
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
|