win16thk.asm

来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 342 行 · 第 1/2 页

ASM
342
字号
;*****************************************************************************
;*
;*                            Open Watcom Project
;*
;*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
;*
;*  ========================================================================
;*
;*    This file contains Original Code and/or Modifications of Original
;*    Code as defined in and that are subject to the Sybase Open Watcom
;*    Public License version 1.0 (the 'License'). You may not use this file
;*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
;*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
;*    provided with the Original Code and Modifications, and is also
;*    available at www.sybase.com/developer/opensource.
;*
;*    The Original Code and all software distributed under the License are
;*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
;*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
;*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
;*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
;*    NON-INFRINGEMENT. Please see the License for the specific language
;*    governing rights and limitations under the License.
;*
;*  ========================================================================
;*
;* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
;*               DESCRIBE IT HERE!
;*
;*****************************************************************************


;****************************************************************************
;***                                                                      ***
;*** WIN16THK.ASM - windows thunk functions                               ***
;***    This set of functions encompasses all possible types of calls.    ***
;***    Each API call has a little stub which generates the appropriate   ***
;***    call into these functions.                                        ***
;***                                                                      ***
;****************************************************************************
.386p

extrn   DPMIGetAliases_:near
extrn   DPMIFreeAlias_:near
extrn   _SaveSP:DWORD           ; save for stack
extrn   _EntryStackSave:DWORD   ; save for stack
extrn   _DataSelector:WORD      ; selector obtained for 32-bit area
extrn   _StackSelector:WORD     ; selector obtained for 32-bit stack
extrn   _FunctionTable:DWORD    ; API function address table

DGROUP group _DATA
;*
;*** 16-bit segment declarations
;*
_TEXT segment word public 'CODE' use16
_TEXT ends

_DATA segment word public 'DATA' use16
_DATA ends

_TEXT segment use16
extrn   __ThunkTable : word
        assume cs:_TEXT
        assume ds:dgroup


        public GetFirst16Alias
        public Get16Alias
GetFirst16Alias proc near
        mov     bp,sp                   ; remember address of first alias
        add     bp,2                    ; ...
Get16Alias:
        pop     cx                      ; get return address
        push    eax                     ; save original pointer value
        test    eax,eax                 ; check for NULL pointer
        je      short L0a               ; if not NULL, then
        cmp     eax,0FFFF0000h          ; see if outside our address space
        jae     short L0b               ; ...
        mov     edx,eax                 ; move eax to dx:ax
        shr     edx,16                  ; ...
        push    ss                      ; set es=ss
        pop     es                      ; ...
        sub     sp,4                    ; allocate space for aliased pointer
        mov     si,sp                   ; point es:si at allocated space
        push    cx                      ; push return address
        mov     cx,1                    ; want 1 alias
        call    DPMIGetAliases_         ; get alias
        mov     es, _DataSelector       ; reload es
        ret                             ; return
L0b:    movzx   eax,ax                  ; zero extend the value
L0a:    push    eax                     ; push aliased pointer
        jmp     cx                      ; return
GetFirst16Alias endp

        public Free16Alias
Free16Alias proc near
        call    dword ptr ds:[bx]       ; call API function
        push    dx                      ; save return value in edi
        push    ax                      ; ...
        pop     edi                     ; ...
L0c:    pop     eax                     ; get aliased pointer
        pop     edx                     ; get original pointer
        cmp     eax,edx                 ; compare them
        je      short L0d               ; if different, then
        shr     eax,16                  ; - get selector
        call    DPMIFreeAlias_          ; - free it
L0d:                                    ; endif
        cmp     sp,bp                   ; are we done?
        jne     L0c                     ; jump if not done
        mov     eax,edi                 ; get return value
        ret                             ; return
Free16Alias endp

;
; __Win16Thunk1 - either there are more than 5 parms, or at least one
;       of the parms is a pointer and requires an alias for it
;       edi - points to parms on 32-bit stack
;
        public  __Win16Thunk1_
__Win16Thunk1_ proc far
        mov     ecx,esp                 ; save 32-bit sp
        mov     _SaveSP,ecx             ; ...
        lss     sp,_EntryStackSave      ; switch to 16-bit stack
        push    ecx                     ; save 32-bit stack pointer
        mov     si,bx                   ; get thunk index
        shr     ebx,16                  ; get API function index
        add     bx,offset _FunctionTable; ...
        call    cs:__ThunkTable[si]        ; call appropriate thunk routine
        pop     ecx                     ; restore 32-bit stack pointer
        mov     word ptr _EntryStackSave,SP     ; save current sp
        mov     bx,_DataSelector        ; load 32-bit data segment
        mov     ss,_StackSelector       ; switch back to 32-bit stack
        mov     esp,ecx                 ; ...
        mov     ds,bx                   ; reload ds
        mov     es,bx                   ; and es
        db      66h                     ; far return to 32-bit code
        ret                             ; ...
__Win16Thunk1_ endp

;
; __Win16Thunk2 - there are less than 6 parms and they have been preloaded
;       into registers.  No aliases are required.
;
        public  __Win16Thunk2_
__Win16Thunk2_ proc far
        mov     _SaveSP,esp             ; save 32-bit stack pointer
        lss     sp,_EntryStackSave      ; switch to 16-bit stack
        push    _SaveSP                 ; save 32-bit sp
        mov     bp,bx                   ; get thunk index
        shr     ebx,16                  ; get API function index
        add     bx,offset _FunctionTable; ...
        call    cs:__ThunkTable[bp]        ; call appropriate thunk routine
        push    dx                      ; load eax with return value
        push    ax                      ; ...
        pop     eax                     ; ...
        pop     ecx                     ; restore 32-bit stack pointer
        mov     word ptr _EntryStackSave,SP     ; save current sp
        mov     bx,_DataSelector        ; load 32-bit data segment
        mov     ss,_StackSelector       ; switch back to 32-bit stack
        mov     esp,ecx                 ; ...
        mov     ds,bx                   ; reload ds
        mov     es,bx                   ; and es
        db      66h                     ; far return to 32-bit code
        ret                             ; ...
__Win16Thunk2_ endp

;
; __Win16Thunk3 - either there are more than 5 parms, or at least one
;       of the parms is a pointer and requires an alias for it.
;       This thunk is the same as __Win16Thunk1 except the return value
;       is a pointer.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?