home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l350 / 3.ddi / EXAMPLES / LOADER / LOAD2.ASM < prev    next >
Encoding:
Assembly Source File  |  1993-01-28  |  3.8 KB  |  128 lines

  1. ;************************************************************************/
  2. ;*    Copyright (C) 1986-1991 Phar Lap Software, Inc.            */
  3. ;*    Unpublished - rights reserved under the Copyright Laws of the    */
  4. ;*    United States.  Use, duplication, or disclosure by the         */
  5. ;*    Government is subject to restrictions as set forth in         */
  6. ;*    subparagraph (c)(1)(ii) of the Rights in Technical Data and     */
  7. ;*    Computer Software clause at 252.227-7013.            */
  8. ;*    Phar Lap Software, Inc., 60 Aberdeen Ave., Cambridge, MA 02138    */
  9. ;************************************************************************/
  10.  
  11.     include dosx.ah
  12.  
  13.            assume cs:code
  14. code    segment dword 'CODE'
  15. comment ~*********************************************************************
  16.  
  17. call_child(ldblkp, ndword_params, param1, ...)
  18. LDEXP_BLK *ldblkp;
  19. ULONG    ndword_params;
  20.  
  21. Description:
  22.     Does a FAR call to the child program, returns when it returns.
  23.     All regs except EAX are preserved;  EAX contains the value returned
  24.     by the child.
  25.  
  26.     The child gets the parameter count as well as the parameters following
  27.     the count on the child's stack.  (Passing the parameter count allows
  28.     this routine to avoid self-modifying code and therefore be reentrant.
  29.     The child params have to be popped after the child returns in order
  30.     to get to parent context saved on the child's stack).
  31.     Note all parameters are passed to the child by value.
  32.  
  33.     For example, if ldblk has the addr of func child(), then use
  34.         call_child(&ldblkp, 2, a, b);
  35.     to make a FAR call to child() defined as follows:
  36.         int _far child(ULONG nparams, ULONG param1, ULONG param2);
  37.  
  38.     NOTE the child must not switch stacks before returning, and must not
  39.     modify the parameter count on the stack.
  40.  
  41. Calling arguments:
  42.     ldblkp        ptr to param block ret'd by load EXP file system call
  43.     ndword_params    number of 4-byte params (folowing count) to pass to 
  44.                 function
  45.  
  46. Returned values:
  47.     Value returned by child program
  48. ~*****************************************************************************
  49.     public    call_child,_call_child,call_child_
  50. _call_child label near
  51. call_child_ label near
  52. call_child proc    near
  53. ;
  54. ; Stack frame
  55. ;
  56. #NDWORD_PARAMS equ (dword ptr 12[ebp])
  57. #LDBLKP    equ    (dword ptr 8[ebp])
  58.  
  59.     push    ebp            ; Set up stack frame
  60.     mov    ebp,esp                ;
  61.     push    ebx            ; save regs
  62.     push    ecx                ;
  63.     push    edx                ;
  64.     push    esi                ;
  65.     push    edi                ;
  66.     push    ds                ;
  67.     push    es                ;
  68.     push    fs                ;
  69.     push    gs                ;
  70.  
  71.     mov    ebx,#LDBLKP        ; get ptr to regs struct
  72.     mov    ax,ss            ; save current stack
  73.     mov    fs,ax                ;
  74.     mov    edx,esp                ;
  75.     lea    esi,#NDWORD_PARAMS    ; save ptr to parameters
  76.     lss    esp,pword ptr [ebx].LX_ESP ; set up child's stack
  77.     push    fs            ; save our old stack on child's stack
  78.     push    edx                ;
  79.     mov    ecx,fs:[esi]        ; get parameter count
  80.     inc    ecx            ; increment because we pass count also
  81.     mov    eax,ecx            ; make room on stack for params
  82.     shl    eax,2                ;
  83.     sub    esp,eax                ;
  84.     mov    ax,ss            ; copy the params to caller's stack
  85.     mov    es,ax                ;
  86.     mov    edi,esp                ;
  87.     rep movs dword ptr es:[edi],fs:[esi]    ;
  88.     push    cs            ; FAR return point below
  89.     lea    eax,#ret            ;
  90.     push    eax                ;
  91.     pushfd                ; set up entry point in child
  92.     movzx    eax,[ebx].LX_CS            ;
  93.     push    eax                ;
  94.     push    [ebx].LX_EIP            ;
  95.     mov    es,[ebx].LX_ES        ; init rest of child's regs
  96.     mov    fs,[ebx].LX_FS            ;
  97.     mov    gs,[ebx].LX_GS            ;
  98.     mov    ds,[ebx].LX_DS            ;
  99.     xor    eax,eax                ;
  100.     xor    ebx,ebx                ;
  101.     xor    ecx,ecx                ;
  102.     xor    edx,edx                ;
  103.     xor    esi,esi                ;
  104.     xor    edi,edi                ;
  105.     xor    ebp,ebp                ;
  106.     iretd                ; transfer control to child
  107. #ret:
  108.     mov    ebx,[esp]        ; pop args off stack (don't wipe out
  109.     inc    ebx                ; return value in EAX
  110.     shl    ebx,2                ;
  111.     add    esp,ebx                ;
  112.     lss    esp,pword ptr [esp]    ; restore our original stack
  113.  
  114.     pop    gs            ; restore regs & return to caller
  115.     pop    fs                ;
  116.     pop    es                ;
  117.     pop    ds                ;
  118.     pop    edi                ;
  119.     pop    esi                ;
  120.     pop    edx                ;
  121.     pop    ecx                ;
  122.     pop    ebx                ;
  123.     pop    ebp                ;
  124.     ret                    ;
  125. call_child endp
  126. code    ends
  127. end
  128.