pushcontext listing .nolist ;; ;; Masm 6.0 --- Windows code include file ;; Copyright (c) Microsoft Corporation. All rights reserved. ;; ;; By Brian Lieuallen 6/26/91 ;; ;; Masm 6.0 has the ability to use user defined macros to ;; generate prologue and epilogue code different from the standard. ;; ;; This used in conjunction with the High Level Lang features of Masm 6.0 ;; Can Eliminate the need for CMACROS.INC. ;; ;; This file will produce prologue and epilogue ;; for the functions of a windows program. ;; ;; This program has two variables which control code generation. ;; ;; ?WINDOWS --- If not zero, it will generate Pro/Epi code for ;; for FAR Windows functions. ;; if zero then it will generate normal code. ;; ;; ?PMODE --- If not zero, it indicates that program will be run under ;; Protect mode windows only. It will now only generate ;; Windows Pro/Epi code for FAR EXPORTED functions. ;; ;; if zero, it generate Windows Pro/Epi code for all ;; FAR functions. ;; ;; Example Declaration ;; ;; WndProc PROC FAR PASCAL EXPORT uses di si, hwnd:WORD, ;; msg:WORD, ;; wParam:WORD, ;; lParam:DWORD ;; local i:word ;; local j:word ;; ;; ; some code ;; ;; WndProc ENDP ;; ;; To use this file indclude the following lines in your assembly program ;; ;; include winpro.inc ;; ?WINDOWS=1 ;; ;; OPTION PROLOGUE:cPrologue ;; OPTION EPILOGUE:cEpilogue ;; ;; The Option lines set the new Pro/Epi code for the assembler ;; ;; To return to the defualt code that the assembler generates use ;; the following lines. ;; ;; OPTION PROLOGUE:PROLOGUEDEF ;; OPTION EPILOGUE:EPILOGUEDEF ifndef ?WINDOWS ;; default to windows code if file included ?WINDOWS = 1 endif ifndef ?PMODE ;; default to real mode compat code ?PMODE = 0 endif ;; cPrologue macro szProcName, flags, cbParams, cbLocals, rgRegs, rgUserParams LOCAL ?Prologue LOCAL ?Stackbytes ?Prologue = 0 if ?WINDOWS NE 0 if (flags AND 0100000b) if (flags AND 10100000b) ?Prologue=1 ;; if windows & far & exported else if (?PMODE NE 0) ?Prologue=0 ;; if windows & far & !exported & protect else ?Prologue=1 ;; if Windows & far & !exported & real endif endif else ?Prologue=0 ;; if Windows & near endif else ?Prologue=0 ;; if !windows endif if ?Prologue EQ 1 ;; Create the loadds code push ds ;; Put DS into AX -- we will place pop ax ;; back in DS later. This sequence nop inc bp ;; walking push bp ;; Create the frame mov bp,sp push ds mov ds,ax ?Stackbytes=cbLocals+2 ;; Return the number of local bytes plus ;; two bytes for pushing DS else push bp ;; .8086 code to gen stack frame mov bp,sp ?Stackbytes = cbLocals ;; Return the number of bytes for locals ;; endif if cbLocals NE 0 sub sp,cbLocals ;; make space on the stack for locals endif ifnb rgRegs ;; There are registers to be saved. do so for r,rgRegs push r endm endif exitm ;; Return the number of bytes on stack after ;; BP was pushed endm ;; cEpilogue macro szProcName, flags, cbParams, cbLocals, rgRegs, rgUserParams LOCAL ?Prologue ?Prologue = 0 if ?WINDOWS NE 0 if (flags AND 0100000b) if (flags AND 10100000b) ?Prologue=1 ;; if windows & far & exported else if (?PMODE NE 0) ?Prologue=0 ;; if windows & far & !exported & protect else ?Prologue=1 ;; if Windows & far & !exported & real endif endif else ?Prologue=0 ;; if Windows & near endif else ?Prologue=0 ;; if !windows endif ifnb rgRegs ;; Pop off the registers -- they are in for r,rgRegs ;; inverse order from the prologue call pop r endm endif if ?Prologue EQ 1 ;; dec bp dec bp mov sp,bp pop ds pop bp dec bp else mov sp,bp ;; else use .8086 compat code pop bp endif if flags AND 010h ;; Caller pops stack arguments ret else ;; Callee pops args if cbParams NE 0 ;; Put out the correct form of return ret cbParams else ret endif endif endm popcontext listing