home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_02_10 / 2n10010b < prev    next >
Text File  |  1991-07-23  |  4KB  |  85 lines

  1. ;=============================================================================
  2. ;
  3. ;    FLATCALL.ASM -- Routine to call 32-bit subroutine from 16-bit WinApp
  4. ;
  5. ;    C calling sequence:
  6. ;       dwResult = FlatCall(lpState, nBytes, args ...)
  7. ;
  8. ;    Where:
  9. ;       DWORD dwResult          32-bit return value from target program
  10. ;       LPSTATE32 lpState       Initial state for 32-bit program
  11. ;       int nBytes              Number of bytes worth of arguments
  12. ;       [any] args              Arguments for target program
  13. ;
  14. ;    Notes:
  15. ;       1. This program is declared _cdecl to facilitate passing a variable
  16. ;          number of arguments. If the target program uses the Pascal
  17. ;          calling convention, the caller must place its arguments in
  18. ;          reverse of the normal order.
  19. ;       2. This program uses no static data and is both reentrant and
  20. ;          suitable for packaging in a DLL.
  21. ;
  22. ;    Written by Walter Oney
  23. ;
  24. ;=============================================================================
  25.  
  26.         name    flatcall
  27.         dosseg
  28.         .model  large,c
  29.         .386p                   ; AFTER model to get use16 defaults
  30.  
  31. state32 struc
  32. s32_tgt df      ?               ; cs:eip of target program
  33. s32_stk df      ?               ; ss:esp of target program
  34. state32 ends
  35.  
  36.         .code
  37. FlatCall proc   uses si di, lpState:dword, nBytes:word, args:word
  38.         push    ds                      ; save caller's DS
  39.  
  40. ;    Extract the arguments from the 16-bit stack before we lose easy
  41. ;    addressability by switching stacks.
  42.  
  43.         lfs     bx, lpState             ; FS:BX -> 32-bit state descriptor
  44.         movzx   ecx, nBytes             ; get # bytes of arguments
  45.         lea     si, args                ; DS:ESI -> target pgm args
  46.         movzx   esi, si                 ;   ..
  47.         mov     ax, ss                  ;   ..
  48.         mov     ds, ax                  ;   ..
  49.         mov     dx, sp                  ; save current SP in DX temporarily
  50.  
  51. ;    Switch to the 32-bit stack used by the target program. Save the
  52. ;    SS:SP belonging to the 16-bit program and copy the arguments for the
  53. ;    target program.
  54.  
  55.         lss     esp, fs:[bx.s32_stk]    ; switch to target pgm stack
  56.  
  57.         push    ds                      ; save 16-bit SS:SP on tgt stack
  58.         push    dx                      ;   ..
  59.  
  60.         sub     esp, ecx                ; backup by size of arguments
  61.         mov     ax, ss                  ; ES:EDI = copy of SS:ESP
  62.         mov     es, ax                  ;   ..
  63.         mov     edi, esp                ;   ..
  64.         cld                             ; be sure of forward direction
  65.         db      0F3h, 67h               ; repeat + address size overrides
  66.         movsb                           ; copy argument onto target stack
  67.  
  68. ;    Call the target program.
  69.  
  70.         mov     ax, ss                  ; force DS == ES == SS
  71.         mov     ds, ax                  ;   ..
  72.         call    fs:[bx.s32_tgt]         ; call the target program
  73.  
  74. ;    Switch back to the 16-bit stack, whose address is on the 32-bit
  75. ;    stack at offset EDI (left over from the MOVSB loop above and preserved
  76. ;    by the target program)
  77.  
  78.         lss     sp, ss:[edi]            ; switch back to 16-bit stack
  79.         mov     edx, eax                ; put 32-bit result into DX:AX
  80.         shr     edx, 16                 ;   ..
  81.         pop     ds                      ; restore caller's DS
  82.         ret                             ; return to caller
  83. FlatCall endp
  84.         end
  85.