windows-nt/Source/XPSP1/NT/multimedia/danim/tools/x86/icecap/prologue.inc
2020-09-26 16:20:57 +08:00

408 lines
8.1 KiB
PHP

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 <rgUserParams> ;; Parse user params if exsisting
for p,<rgUserParams> ;; For every user param
ifidni <p>, <CHECKSTACK> ;; Is it checkstack?
?checkstack = 1 ;; Yes -- do checkstack
endif
ifidni <p>, <NOCHECKSTACK> ;; Don't do checkstack?
?checkstack = 0 ;; Yes -- clear checkstack
endif
ifidni <p>, <LOADDS> ;; Is it LoadDS
?loadds = 1 ;; Yes -- do loadds sequence
endif
ifidni <p>, <NOLOADDS> ;; Don't do LoadDS?
?loadds = 0 ;; Yes -- clear loadds flag
endif
ifidni <p>, <INCBP> ;; Is it IncBP
if flags AND 020h ;; and far?
?incbp = 1 ;; Yes -- do IncBP sequence
endif
endif
ifidni <p>, <NOINCBP> ;; Is it NoIncBP
?incbp = 0 ;; Yes -- Clear the incbp flag
endif
ifidni <p>, <FORCEFRAME> ;; Is it ForceFrame?
?doPrologue = 1 ;; Yes -- force out a frame
endif
ifidni <p>, <PROFILE>
?doProfile = 1
endif
ifidni <p>, <NOPROFILE>
?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 <?cbLocals>
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 <rgUserParams> ;; Parse user params if exsisting
for p,<rgUserParams> ;; For every user param
ifidni <p>, <CHECKSTACK> ;; Is it checkstack?
?checkstack = 1 ;; Yes -- do checkstack
endif
ifidni <p>, <NOCHECKSTACK> ;; Don't do checkstack?
?checkstack = 0 ;; Yes -- clear checkstack
endif
ifidni <p>, <LOADDS> ;; Is it LoadDS
?loadds = 1 ;; Yes -- do loadds sequence
endif
ifidni <p>, <NOLOADDS> ;; Don't do LoadDS?
?loadds = 0 ;; Yes -- clear loadds flag
endif
ifidni <p>, <INCBP> ;; Is it IncBP
if flags AND 020h
?incbp = 1 ;; Yes -- do IncBP sequence
endif
endif
ifidni <p>, <NOINCBP> ;; Is it NoIncBP
?incbp = 0 ;; Yes -- Clear the incbp flag
endif
ifidni <p>, <FORCEFRAME> ;; 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