home *** CD-ROM | disk | FTP | other *** search
- ;************************************************************************/
- ;* Copyright (C) 1986-1991 Phar Lap Software, Inc. */
- ;* Unpublished - rights reserved under the Copyright Laws of the */
- ;* United States. Use, duplication, or disclosure by the */
- ;* Government is subject to restrictions as set forth in */
- ;* subparagraph (c)(1)(ii) of the Rights in Technical Data and */
- ;* Computer Software clause at 252.227-7013. */
- ;* Phar Lap Software, Inc., 60 Aberdeen Ave., Cambridge, MA 02138 */
- ;************************************************************************/
-
- include dosx.ah
-
- assume cs:code
- code segment dword 'CODE'
- comment ~*********************************************************************
-
- call_child(ldblkp, ndword_params, param1, ...)
- LDEXP_BLK *ldblkp;
- ULONG ndword_params;
-
- Description:
- Does a FAR call to the child program, returns when it returns.
- All regs except EAX are preserved; EAX contains the value returned
- by the child.
-
- The child gets the parameter count as well as the parameters following
- the count on the child's stack. (Passing the parameter count allows
- this routine to avoid self-modifying code and therefore be reentrant.
- The child params have to be popped after the child returns in order
- to get to parent context saved on the child's stack).
- Note all parameters are passed to the child by value.
-
- For example, if ldblk has the addr of func child(), then use
- call_child(&ldblkp, 2, a, b);
- to make a FAR call to child() defined as follows:
- int _far child(ULONG nparams, ULONG param1, ULONG param2);
-
- NOTE the child must not switch stacks before returning, and must not
- modify the parameter count on the stack.
-
- Calling arguments:
- ldblkp ptr to param block ret'd by load EXP file system call
- ndword_params number of 4-byte params (folowing count) to pass to
- function
-
- Returned values:
- Value returned by child program
- ~*****************************************************************************
- public call_child,_call_child,call_child_
- _call_child label near
- call_child_ label near
- call_child proc near
- ;
- ; Stack frame
- ;
- #NDWORD_PARAMS equ (dword ptr 12[ebp])
- #LDBLKP equ (dword ptr 8[ebp])
-
- push ebp ; Set up stack frame
- mov ebp,esp ;
- push ebx ; save regs
- push ecx ;
- push edx ;
- push esi ;
- push edi ;
- push ds ;
- push es ;
- push fs ;
- push gs ;
-
- mov ebx,#LDBLKP ; get ptr to regs struct
- mov ax,ss ; save current stack
- mov fs,ax ;
- mov edx,esp ;
- lea esi,#NDWORD_PARAMS ; save ptr to parameters
- lss esp,pword ptr [ebx].LX_ESP ; set up child's stack
- push fs ; save our old stack on child's stack
- push edx ;
- mov ecx,fs:[esi] ; get parameter count
- inc ecx ; increment because we pass count also
- mov eax,ecx ; make room on stack for params
- shl eax,2 ;
- sub esp,eax ;
- mov ax,ss ; copy the params to caller's stack
- mov es,ax ;
- mov edi,esp ;
- rep movs dword ptr es:[edi],fs:[esi] ;
- push cs ; FAR return point below
- lea eax,#ret ;
- push eax ;
- pushfd ; set up entry point in child
- movzx eax,[ebx].LX_CS ;
- push eax ;
- push [ebx].LX_EIP ;
- mov es,[ebx].LX_ES ; init rest of child's regs
- mov fs,[ebx].LX_FS ;
- mov gs,[ebx].LX_GS ;
- mov ds,[ebx].LX_DS ;
- xor eax,eax ;
- xor ebx,ebx ;
- xor ecx,ecx ;
- xor edx,edx ;
- xor esi,esi ;
- xor edi,edi ;
- xor ebp,ebp ;
- iretd ; transfer control to child
- #ret:
- mov ebx,[esp] ; pop args off stack (don't wipe out
- inc ebx ; return value in EAX
- shl ebx,2 ;
- add esp,ebx ;
- lss esp,pword ptr [esp] ; restore our original stack
-
- pop gs ; restore regs & return to caller
- pop fs ;
- pop es ;
- pop ds ;
- pop edi ;
- pop esi ;
- pop edx ;
- pop ecx ;
- pop ebx ;
- pop ebp ;
- ret ;
- call_child endp
- code ends
- end
-