pushcontext listing .nolist ; ; (C) Copyright Microsoft Corporation 1992, 1995 ; This file is used to create the same sets of prologue and epilogue ; sequences which the Microsoft C 6.00 compiler will produce. This ; file would be used for writing windows programs and to provide ; such features as stack checking in the assembler portions of ; a C based project. ; The following global variables will affect the prolog/epilog ; sequences produced ; ; PROFILE - If 1 then __penter calls will be inserted in all prologs ; ?WP_DEBUG - If 1 then prolog/epilog sequences will be forced ; ?WP_CHECKSTACK - If 1 then a check stack will be forced on all ; procedures ; ?WP_INCBP - If 1 then the inc bp sequence will be generated on ; all far procedures ; ?WP_LOADDS - If 1 then the load ds sequence will be generated on ; all far procedures ; ifndef ?WP_DEBUG ?WP_DEBUG = 0 endif ifndef ?WP_CHECKSTACK ?WP_CHECKSTACK = 0 endif ifndef ?WP_INCBP ?WP_INCBP = 0 endif ifndef ?WP_LOADDS ?WP_LOADDS = 0 endif ifndef PROFILE PROFILE = 0 endif ; ; Complain if we are in a segment as this will affect how the ; externdefs are done and therefore the fixups and code ; created on the checkstack calls ; % ifnb <@CurSeg> echo Include should not be contained in a segment endif externdef C _aNchkstk:near ; Extern the symbols externdef C _aFchkstk:far ; for later reference externdef C _penter:near ; ; This macro will produce the same output as will the ; C6 compiler for the given switches. ; ; The following may be placed in the MacroArgs field of the ; proc defintion: ; ; CHECKSTACK ; NOCHECKSTACK ; LOADDS ; NOLOADDS ; FORCEFRAME ; INCBP ; NOINCBP ; PROFILE option prologue:cPrologue cPrologue macro szProcName, flags, cbParams, cbLocals, rgRegs, rgUserParams LOCAL ?doPrologue LOCAL ?loadds LOCAL ?checkstack LOCAL ?incbp LOCAL ?cbLocals LOCAL ?doProfile ; pushcontext listing ; .nolistmacro ; .listmacroall ?doPrologue = 0 ?loadds = 0 ?checkstack = 0 ?incbp = 0 ?cbLocals = cbLocals ?doProfile = 0 ;; Set the defaults based on the global values specified ;; if ?WP_DEBUG NE 0 ;; Force frames by default ?doPrologue = 1 endif if ?WP_CHECKSTACK NE 0 ;; Force checkstack by default ?checkstack = 1 endif if ?WP_INCBP NE 0 ;; Force incbp by default if far if flags AND 020h ?incbp = 1 endif endif if ?WP_LOADDS NE 0 ;; Force loadds by default if far if flags AND 020h ?loadds = 1 endif endif if PROFILE NE 0 ;; profiling wanted ?doProfile = 1 ;; turn on profiling endif ;; ;; Get all of the user parameters parsed ;; ifnb ;; Parse user params if exsisting for p, ;; For every user param ifidni

, ;; Is it checkstack? ?checkstack = 1 ;; Yes -- do checkstack endif ifidni

, ;; Don't do checkstack? ?checkstack = 0 ;; Yes -- clear checkstack endif ifidni

, ;; Is it LoadDS ?loadds = 1 ;; Yes -- do loadds sequence endif ifidni

, ;; Don't do LoadDS? ?loadds = 0 ;; Yes -- clear loadds flag endif ifidni

, ;; Is it IncBP if flags AND 020h ;; and far? ?incbp = 1 ;; Yes -- do IncBP sequence endif endif ifidni

, ;; Is it NoIncBP ?incbp = 0 ;; Yes -- Clear the incbp flag endif ifidni

, ;; Is it ForceFrame? ?doPrologue = 1 ;; Yes -- force out a frame endif ifidni

, ?doProfile = 1 endif ifidni

, ?doProfile = 0 endif endm ;; End of user parameter parsing loop endif ;; Turn off options that don't make sense in USE32 segment if @WordSize eq 4 ?checkstack = 0 ?loadds = 0 ?incbp = 0 endif ;; Frames are generated iff ;; 1. cbLocals + cbParams != 0 ;; 2. FORCEFRAME is set ;; 3. INCBP is set and proc is far ;; 4. LOADDS is set ;; ;; Force a prolog? ?doPrologue = ?doPrologue OR ?incbp OR ?loadds OR ?checkstack OR (?cbLocals NE 0) OR (cbParams NE 0) if ?doProfile EQ 1 ;; generate profiling call call _penter endif if ?doPrologue EQ 0 ;; No prolog needed -- so get out of here ; popcontext listing exitm<0> endif if ?loadds EQ 1 ;; Create the loadds code -- force in push ds ;; Put DS into AX -- we will place pop ax ;; back in DS later. This sequence nop ;; is altered by the OS if needed endif if ?incbp EQ 1 ;; Mark as a far procedure for stack inc bp ;; walking endif if @WordSize eq 4 push ebp mov ebp, esp else push bp ;; Create the frame mov bp,sp endif if ?loadds EQ 1 ;; Load up DS with the value in AX push ds ;; mov ds,ax ;; ?cbLocals = ?cbLocals + 2 endif if ?checkstack EQ 1 ;; Now allocate space for locals mov ax,cbLocals ;; # of bytes of locals (unadjusted) % ifidni <@CurSeg>, <_TEXT> call _aNchkstk ;; Call run time routine to allocate else call _aFchkstk endif else ; ?checkstack NE 1 if cbLocals NE 0 if @WordSize eq 4 sub esp, cbLocals else sub sp,cbLocals ;; make space on the stack for locals endif endif endif ifnb rgRegs ;; There are registers to be saved. do so for r,rgRegs push r endm endif ; popcontext listing exitm endm ; ; This macro will produce the same output as will the ; C6 compiler for the given switches. ; ; The following may be placed in the MacroArgs field of the ; proc defintion: ; ; CHECKSTACK ; NOCHECKSTACK ; LOADDS ; NOLOADDS ; FORCEFRAME ; INCBP ; NOINCBP option epilogue:cEpilogue cEpilogue macro szProcName, flags, cbParams, cbLocals, rgRegs, rgUserParams LOCAL ?doPrologue LOCAL ?loadds LOCAL ?checkstack LOCAL ?incbp ; pushcontext listing ; .nolistmacro ; .listmacroall ?doPrologue = 0 ?loadds = 0 ?checkstack = 0 ?incbp = 0 ;; Turn off options that don't make sense in USE32 segment if @WordSize eq 4 ?checkstack = 0 ?loadds = 0 ?incbp = 0 endif ;; Set the defaults based on the global values specified ;; if ?WP_DEBUG NE 0 ;; Force frames by default ?doPrologue = 1 endif if ?WP_CHECKSTACK NE 0 ;; Force checkstack by default ?checkstack = 1 endif if ?WP_INCBP NE 0 ;; Force incbp by default if flags AND 020h ?incbp = 1 endif endif if ?WP_LOADDS NE 0 ;; Force loadds by default if flags AND 020h ?loadds = 1 endif endif ;; ;; Get all of the user parameters parsed ;; ifnb ;; Parse user params if exsisting for p, ;; For every user param ifidni

, ;; Is it checkstack? ?checkstack = 1 ;; Yes -- do checkstack endif ifidni

, ;; Don't do checkstack? ?checkstack = 0 ;; Yes -- clear checkstack endif ifidni

, ;; Is it LoadDS ?loadds = 1 ;; Yes -- do loadds sequence endif ifidni

, ;; Don't do LoadDS? ?loadds = 0 ;; Yes -- clear loadds flag endif ifidni

, ;; Is it IncBP if flags AND 020h ?incbp = 1 ;; Yes -- do IncBP sequence endif endif ifidni

, ;; Is it NoIncBP ?incbp = 0 ;; Yes -- Clear the incbp flag endif ifidni

, ;; Is it ForceFrame? ?doPrologue = 1 ;; Yes -- force out a frame endif endm ;; End of user parameter parsing loop endif ;; Turn off options that don't make sense in USE32 segment if @WordSize eq 4 ?checkstack = 0 ?loadds = 0 ?incbp = 0 endif ;; Frames are generated iff ;; 1. cbLocals + cbParams != 0 ;; 2. FORCEFRAME is set ;; 3. INCBP is set and proc is far ;; 4. LOADDS is set ;; ;; Force a prolog? ?doPrologue = ?doPrologue OR ?incbp OR ?loadds OR ?checkstack OR (cbLocals NE 0) OR (cbParams NE 0) if ?doPrologue EQ 0 ;; No epilog needed -- so get out of here ret exitm endif ifnb rgRegs ;; Pop off the registers -- they are in for r,rgRegs ;; inverse order from the prologue call pop r endm endif if ?loadds ;; dec bp dec bp mov sp,bp pop ds pop bp else if @WordSize eq 4 mov esp, ebp pop ebp else mov sp,bp pop bp endif endif if ?incbp ;; Remove the increment of BP if necessary dec 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 .listmacro