|
|
;++ ; ; WOW v1.0 ; ; Copyright (c) 1991, Microsoft Corporation ; ; WINSTACK.ASM ; Win16 stack munging routines ; ; History: ; ; Created 18-Jun-1991 by Jeff Parsons (jeffpar) ; Copied from WIN31 and edited (as little as possible) for WOW16 ;--
;**************************************************************************** ;* * ;* WINSTACK.ASM - * ;* * ;* Stack Frame setup routines * ;* * ;****************************************************************************
ifdef WOW NOEXTERNS equ 1 endif .xlist include user.inc .list
; ; Short jump macro ; jmps macro adr jmp short (adr) endm
; ; XMOV macro ; ; Use instead of MOV ax,reg. Saves a byte. ; xmov macro a,b xchg a,b endm
ifdef WOWDEBUG sBegin DATA
externW <pStackTop> externW <pStackMin> externW <pStackBot>
sEnd
ifdef DEBUG
sBegin TEXT ExternFP <DivideByZero> sEnd
endif endif ;WOWDEBUG
createSeg _TEXT, TEXT, WORD, PUBLIC, CODE
assumes CS,TEXT assumes SS,DATA
sBegin TEXT
org 0 ; MUST be at the start of each segment ; so that WinFarFrame can jump back ; to the proper location.
;*--------------------------------------------------------------------------* ;* * ;* _TEXT_NEARFRAME() - * ;* * ;*--------------------------------------------------------------------------*
; Call to _segname_NEARFRAME should be in following format: ; ; call _segname_NEARFRAME ; db cbLocals (count of local words to be allocated) ; db cbParams (count of argument words)
LabelNP <PUBLIC, _TEXT_NEARFRAME> push cs ; Save the current segment jmps WinNearFrame ; Jump to the (only) NEARFRAME routine nop nop nop
nf2: push cs ; Save the CS (it may have changed!) jmps WinNearFrame2 ; Jump to the second half of NEARFRAME nop nop nop
;*--------------------------------------------------------------------------* ;* * ;* _TEXT_FARFRAME() - * ;* * ;*--------------------------------------------------------------------------*
; Call to _segname_FARFRAME should be in following format: ; ; call _segname_FARFRAME ; db cbLocals (count of local words to be allocated) ; db cbParams (count of argument words)
LabelNP <PUBLIC, _TEXT_FARFRAME> push cs ; Save the current segment jmps WinFarFrame ; Jump to the (only) FARFRAME routine nop nop nop
ifdef WOWDEBUG ff2: jmp near ptr WinFarFrame2 ; Jump to the second half of FARFRAME else ff2: jmp short near ptr WinFarFrame2 endif
ifdef WOWDEBUG ;*--------------------------------------------------------------------------* ;* * ;* __astkovr1() - * ;* * ;*--------------------------------------------------------------------------*
; Stack Overflow checking routine
;externFP <__astkovr>
;__astkovr1: jmp __astkovr
endif
;*--------------------------------------------------------------------------* ;* * ;* WinNearFrame() - * ;* * ;*--------------------------------------------------------------------------*
; Sets up and dismantles the frame for a NEAR routine. This routine ; is FAR JMPed to by _segname_NEARFRAME. It munges the stack so that a ; NEAR RET returns to a JMP to WinNearFrame2 which dismantles the frame. ; ; CX must be is preserved in the first portion.
LabelFP <PUBLIC, WinNearFrame> pop es ; Get the caller's Code Segment pop bx ; Get pointer to sizes of args and locals
push bp ; Update the BP chain mov bp,sp
mov dx,word ptr es:[bx] ; Move the 2 parms in DX
xor ax,ax mov al,dl ; Move the # of local words into AL shl ax,1 ; Convert # of words into # of bytes
ifdef WOWDEBUG sub ax,sp ; jae __astkovr1 ; Check for stack overflow in neg ax ; debugging versions cmp ss:[pStackTop],ax ; ja __astkovr1 cmp ss:[pStackMin],ax jbe nf100 mov ss:[pStackMin],ax nf100: xmov sp,ax
else sub sp,ax ; Reserve room for locals on stack endif
push si ; Save SI and DI push di
xor ax,ax mov al,dh ; Move the # of func args into AL shl ax,1 ; Convert words to bytes push ax ; Save on the stack
mov ax,offset nf2 ; Push the offset of the JMP to push ax ; WinNearFrame2 for function's RET
inc bx ; Move pointer past the parms to the inc bx ; actual function code
push es ; Jump back to the function via RETF push bx
xor bx,bx ; insure ES is 0 mov es,bx
retf
LabelFP <PUBLIC,WinNearFrame2> ; NOTE: AX and DX must be preserved now since they contain the C ; return value. pop es ; Get the caller's CS pop cx ; Get # of func args in CX
pop di ; Restore SI and DI pop si
mov sp,bp ; Free the local variables pop bp ; Restore BP
pop bx ; Get the caller's return address
add sp,cx ; Remove paramters from stack
push es ; Return to caller via RETF push bx
xor bx,bx ; insure ES is 0 mov es,bx
retf
;*--------------------------------------------------------------------------* ;* * ;* WinFarFrame() - * ;* * ;*--------------------------------------------------------------------------*
; Sets up and dismantles the frame for a FAR routine. This routine ; is FAR JMPed to by _segname_NEARFRAME. It munges the stack so that a ; NEAR RET returns to a JMP to WinFarFrame2 which dismantles the frame. ; ; CX must be is preserved in the first portion.
LabelFP <PUBLIC, WinFarFrame> mov ax,ds ; This is patched by the loader to become nop ; mov ax,DSVAL
pop es ; Get the caller's CS
pop bx ; Get pointer to sizes of args and locals
inc bp ; Make BP odd to mark far frame push bp ; Update the BP chain mov bp,sp
push ds ; Save DS mov dx,word ptr es:[bx] ; Move the 2 parms into DX
mov ds,ax ; Get the new DS from the loader patch
xor ax,ax mov al,dl ; Move the # of local words into AL shl ax,1 ; Convert # of words into # of bytes
ifdef WOWDEBUG sub ax,sp ; jae __astkovr1 ; Check for stack overflow in neg ax ; debugging versions cmp ss:[pStackTop],ax ; ja __astkovr1 cmp ss:[pStackMin],ax jbe ff100 mov ss:[pStackMin],ax ff100: xmov sp,ax
else sub sp,ax ; Reserve room for locals on stack endif
push si ; Save SI and DI push di
xor ax,ax mov al,dh ; Move the # of func args into AL shl ax,1 ; Convert words to bytes push ax ; Save on the stack
mov ax,offset ff2 ; Push the offset of the JMP to push ax ; WinFarFrame2 for function's RET
inc bx ; Move pointer past the parms to the inc bx ; actual function code
push es ; Jump back to the function via RETF push bx
xor bx,bx ; Ensure es is 0 mov es,bx retf
LabelFP <PUBLIC,WinFarFrame2> ; NOTE: AX and DX must be preserved now since they contain the C ; return value. pop cx ; Get # of func args in CX
pop di ; Restore SI and DI pop si
if 0 sub bp,2 ; Point BP at the DS value mov sp,bp ; Free the local variables pop ds ; Restore DS pop bp ; Restore BP dec bp ; Make BP even again
pop bx ; Get the caller's return address pop es
add sp,cx ; Remove paramters from stack
push es ; Return to caller via RETF push bx
xor bx,bx ; Ensure es is 0 mov es,bx endif
mov ds,[bp-2] ; Restore DS lea bx,[bp+2] ; get caller's return address add bx,cx ; Where we want to put the old CS:IP mov cx,[bp+4] ; get old CS mov ss:[bx+2],cx ; move it up mov cx,[bp+2] ; Get old IP mov ss:[bx],cx ; move it up mov bp,[bp] ; restore the old BP dec bp ; make it even again mov sp,bx ; point to the moved CS:IP retf ; later dude
ifdef WOWDEBUG
ORG 0cch jmp far ptr DivideByZero endif
sEnd TEXT
ifndef WOW ;============================================================================== ; FFFE SEGMENT ;==============================================================================
createSeg _FFFE, FFFE, BYTE, PUBLIC, CODE
assumes CS,_FFFE assumes SS,DATA
sBegin FFFE
ORG 0 ; This segment must have a magic header ; so that we know to move it up into ; segment FFFE:0000 if possible ; db 16 DUP ("AC") ; db 16 DUP (0) ; Tony's sleazy zeros
ifdef WOWDEBUG ;*--------------------------------------------------------------------------* ;* * ;* __ffastkovr1() - * ;* * ;*--------------------------------------------------------------------------*
; Stack Overflow checking routine
;__ffastkovr1: jmp __astkovr
endif
;*--------------------------------------------------------------------------* ;* * ;* _FFFE_NEARFRAME() - * ;* * ;*--------------------------------------------------------------------------*
LabelNP <PUBLIC, _FFFE_NEARFRAME> pop bx ; Get pointer to sizes of args and locals
push bp ; Update the BP chain mov bp,sp
mov dx,word ptr cs:[bx] ; Move the 2 parms in DX
xor ax,ax mov al,dl ; Move the # of local words into AL shl ax,1 ; Convert # of words into # of bytes
ifdef WOWDEBUG sub ax,sp ; jae __ffastkovr1 ; Check for stack overflow in neg ax ; debugging versions cmp ss:[pStackTop],ax ; ja __ffastkovr1 cmp ss:[pStackMin],ax jbe ffnf100 mov ss:[pStackMin],ax ffnf100: xmov sp,ax
else sub sp,ax ; Reserve room for locals on stack endif
push si ; Save SI and DI push di
xor ax,ax mov al,dh ; Move the # of func args into AL shl ax,1 ; Convert words to bytes push ax ; Save on the stack
ifndef userhimem mov ax,offset FFFE_nf2 ; Munge the stack so the function else push ds mov ax, _INTDS mov ds,ax assumes ds,INTDS mov ax,fffedelta pop ds assumes ds,DATA add ax, OFFSET FFFE_nf2 endif push ax ; "returns" to FFFE_nf2
inc bx ; Move pointer past the parms to the inc bx ; actual function code
push bx ; Jump back to the function ret
LabelFP <PUBLIC,FFFE_nf2> ; NOTE: AX and DX must be preserved now since they contain the C ; return value pop cx ; Get # of func args in CX
pop di ; Restore SI and DI pop si
mov sp,bp ; Free the local variables pop bp ; Restore BP
pop bx ; Get the caller's return address
add sp,cx ; Remove paramters from stack
push bx ; Return to caller ret
;*--------------------------------------------------------------------------* ;* * ;* _FFFE_FARFRAME() - * ;* * ;*--------------------------------------------------------------------------*
LabelNP <PUBLIC, _FFFE_FARFRAME> mov ax,ds ; This is patched by the loader to become nop ; mov ax,DSVAL
pop bx ; Get pointer to sizes of args and locals
inc bp ; Make BP odd to mark far frame push bp ; Update the BP chain mov bp,sp
push ds ; Save DS mov ds,ax ; Get the new DS from the loader patch
mov dx,word ptr cs:[bx] ; Move the 2 parms into DX
xor ax,ax mov al,dl ; Move the # of local words into AL shl ax,1 ; Convert # of words into # of bytes
ifdef WOWDEBUG sub ax,sp ; jae __ffastkovr1 ; Check for stack overflow in neg ax ; debugging versions cmp ss:[pStackTop],ax ; ja __ffastkovr1 cmp ss:[pStackMin],ax jbe ffff100 mov ss:[pStackMin],ax ffff100: xmov sp,ax
else sub sp,ax ; Reserve room for locals on stack endif
push si ; Save SI and DI push di
xor ax,ax mov al,dh ; Move the # of func args into AL shl ax,1 ; Convert words to bytes push ax ; Save on the stack
ifndef userhimem mov ax,offset FFFE_ff2 ; Munge the stack so the function else push ds mov ax, _INTDS mov ds,ax assumes ds,INTDS mov ax,fffedelta pop ds assumes ds,DATA add ax,offset FFFE_ff2 ; Munge the stack so the function endif push ax ; "returns" to FFFE_nf2
inc bx ; Move pointer past the parms to the inc bx ; actual function code
push bx ; Jump back to the function ret
; NOTE: AX and DX must be preserved now since they contain the C ; return value
LabelFP <PUBLIC,FFFE_ff2> pop cx ; Get # of func args in CX
pop di ; Restore SI and DI pop si
sub bp,2 ; Point BP at the DS value mov sp,bp ; Free the local variables pop ds ; Restore DS pop bp ; Restore BP dec bp ; Make BP even again
pop bx ; Get the caller's return address pop es
add sp,cx ; Remove paramters from stack
push es ; Return to caller via RETF push bx
xor bx,bx ; Ensure es is 0 mov es,bx retf
sEnd FFFE
;*--------------------------------------------------------------------------* ;* * ;* CreateFrame Macro - * ;* * ;*--------------------------------------------------------------------------*
CreateFrame macro SegName
createSeg _&SegName, SegName, BYTE, PUBLIC, CODE
assumes CS,_&SegName assumes SS,DATA
sBegin SegName
org 0 ; MUST be at the start of each segment ; so that WinFarFrame can jump back ; to the proper location.
LabelNP <PUBLIC, _&SegName&_NEARFRAME> push cs ; Save the current segment jmp WinNearFrame ; Jump to the (only) NEARFRAME routine push cs ; Save the CS (it may have changed!) jmp WinNearFrame2 ; Jump to the second half of NEARFRAME
LabelNP <PUBLIC, _&SegName&_FARFRAME> push cs ; Save the current segment jmp WinFarFrame ; Jump to the (only) FARFRAME routine jmp WinFarFrame2 ; Jump to the second half of FARFRAME
sEnd SegName
endm
;============================================================================== ; SEGMENT FRAMES ;==============================================================================
;CreateFrame INIT ;CreateFrame MDKEY ;CreateFrame MENUCORE ;CreateFrame MENUAPI ;CreateFrame MENUSTART ;CreateFrame RUNAPP ;CreateFrame DLGBEGIN ;CreateFrame DLGCORE ;CreateFrame SCRLBAR CreateFrame WMGR CreateFrame WMGR2 ;CreateFrame RARE ;CreateFrame LBOX ;CreateFrame LBOXAPI ;CreateFrame LBOXDIR ;CreateFrame LBOXMULTI ;CreateFrame LBOXRARE ;CreateFrame CLPBRD ;CreateFrame COMDEV ;CreateFrame ICON ;CreateFrame SWITCH ;CreateFrame MSGBOX ;CreateFrame MDIWIN ;CreateFrame MDIMENU ;CreateFrame EDECRARE ;CreateFrame EDSLRARE ;CreateFrame EDMLONCE ;CreateFrame EDMLRARE ;CreateFrame WINCRTDST ;CreateFrame WINUTIL ;CreateFrame RESOURCE ;CreateFrame WALLPAPER ;CreateFrame WINSWP CreateFrame LANG
endif ;WOW
end
|