142 lines
3.7 KiB
NASM
142 lines
3.7 KiB
NASM
|
|
; Copyright Oliver Kowalke 2009.
|
|
; Distributed under the Boost Software License, Version 1.0.
|
|
; (See accompanying file LICENSE_1_0.txt or copy at
|
|
; http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
; ---------------------------------------------------------------------------------
|
|
; | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|
|
; ---------------------------------------------------------------------------------
|
|
; | 0h | 04h | 08h | 0ch | 010h | 014h | 018h | 01ch |
|
|
; ---------------------------------------------------------------------------------
|
|
; | fc_mxcsr|fc_x87_cw| fc_strg |fc_deallo| limit | base | fc_seh | EDI |
|
|
; ---------------------------------------------------------------------------------
|
|
; ---------------------------------------------------------------------------------
|
|
; | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
|
|
; ---------------------------------------------------------------------------------
|
|
; | 020h | 024h | 028h | 02ch | 030h | 034h | 038h | 03ch |
|
|
; ---------------------------------------------------------------------------------
|
|
; | ESI | EBX | EBP | EIP | EXIT | | SEH NXT |SEH HNDLR|
|
|
; ---------------------------------------------------------------------------------
|
|
|
|
.386
|
|
.XMM
|
|
.model flat, c
|
|
.code
|
|
|
|
jump_fcontext PROC EXPORT
|
|
; fourth arg of jump_fcontext() == flag indicating preserving FPU
|
|
mov ecx, [esp+010h]
|
|
|
|
push ebp ; save EBP
|
|
push ebx ; save EBX
|
|
push esi ; save ESI
|
|
push edi ; save EDI
|
|
|
|
assume fs:nothing
|
|
; load NT_TIB into ECX
|
|
mov edx, fs:[018h]
|
|
assume fs:error
|
|
|
|
; load current SEH exception list
|
|
mov eax, [edx]
|
|
push eax
|
|
|
|
; load current stack base
|
|
mov eax, [edx+04h]
|
|
push eax
|
|
|
|
; load current stack limit
|
|
mov eax, [edx+08h]
|
|
push eax
|
|
|
|
; load current deallocation stack
|
|
mov eax, [edx+0e0ch]
|
|
push eax
|
|
|
|
; load fiber local storage
|
|
mov eax, [edx+010h]
|
|
push eax
|
|
|
|
; prepare stack for FPU
|
|
lea esp, [esp-08h]
|
|
|
|
; test for flag preserve_fpu
|
|
test ecx, ecx
|
|
je nxt1
|
|
|
|
; save MMX control- and status-word
|
|
stmxcsr [esp]
|
|
; save x87 control-word
|
|
fnstcw [esp+04h]
|
|
|
|
nxt1:
|
|
; first arg of jump_fcontext() == context jumping from
|
|
mov eax, [esp+030h]
|
|
|
|
; store ESP (pointing to context-data) in EAX
|
|
mov [eax], esp
|
|
|
|
; second arg of jump_fcontext() == context jumping to
|
|
mov edx, [esp+034h]
|
|
|
|
; third arg of jump_fcontext() == value to be returned after jump
|
|
mov eax, [esp+038h]
|
|
|
|
; restore ESP (pointing to context-data) from EDX
|
|
mov esp, edx
|
|
|
|
; test for flag preserve_fpu
|
|
test ecx, ecx
|
|
je nxt2
|
|
|
|
; restore MMX control- and status-word
|
|
ldmxcsr [esp]
|
|
; restore x87 control-word
|
|
fldcw [esp+04h]
|
|
|
|
nxt2:
|
|
; prepare stack for FPU
|
|
lea esp, [esp+08h]
|
|
|
|
assume fs:nothing
|
|
; load NT_TIB into ECX
|
|
mov edx, fs:[018h]
|
|
assume fs:error
|
|
|
|
; restore fiber local storage
|
|
pop ecx
|
|
mov [edx+010h], ecx
|
|
|
|
; restore current deallocation stack
|
|
pop ecx
|
|
mov [edx+0e0ch], ecx
|
|
|
|
; restore current stack limit
|
|
pop ecx
|
|
mov [edx+08h], ecx
|
|
|
|
; restore current stack base
|
|
pop ecx
|
|
mov [edx+04h], ecx
|
|
|
|
; restore current SEH exception list
|
|
pop ecx
|
|
mov [edx], ecx
|
|
|
|
pop edi ; save EDI
|
|
pop esi ; save ESI
|
|
pop ebx ; save EBX
|
|
pop ebp ; save EBP
|
|
|
|
; restore return-address
|
|
pop edx
|
|
|
|
; use value in EAX as return-value after jump
|
|
; use value in EAX as first arg in context function
|
|
mov [esp+04h], eax
|
|
|
|
; indirect jump to context
|
|
jmp edx
|
|
jump_fcontext ENDP
|
|
END |