⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmacros.inc

📁 C-编译器的设计文档与源代码下载,1. 具有比较友好的GUI界面(仿照了我自己正在用的emacs); 2. 语法支持比较全面(毕竟是C-
💻 INC
📖 第 1 页 / 共 3 页
字号:
ife ?t_&n
	push	word ptr (n)
exitm
endif
endif
	push	n
endm

;;	cCall - call a 'c' language procedure
;;
;;	The given procedure is called with the given parameters.
;;	If the calling convention is C, the arguments are pushed
;;      in reverse order, and removed after the called procedure
;;	returns.  If the calling conventing is PL/M, the arguments
;;      are pushed as they were encountered, and the called procedure
;;      is assumed to have removed them from the stack.
;;
;;	The calling convention priority will be:
;;	   1)	that specified on the cCall if present
;;	   2)	that defined by the target
;;	   3)	the default (?PLM flag)
;;
;;      format:
;;		ccall n,<a>,c
;;
;;      where:
;;              n       is the name of the procedure to call
;;              a       are arguments to be pushed (optional, may be
;;                      specified with the "arg" macro.
;;		c	is the convention, C for C, PLM or PSACAL for PL/M.
;;			The default (?PLM flag) will be used if not specified.

cCall macro n,a,c
ifnb <a>
arg <a>
endif
mpush %?rsl
ifdef ?CC&n
?cCall1=?CC&n
else
?cCall1=?PLM
endif
ifnb <c>
?gcc ?cCall1,%?cCall1,<c>
endif
?argl=0
ife ?cCall1
?acb=?argc
else
?acb=1
endif
rept ?argc
uconcat <?ali>,%?acb
uconcat <purge>,,<?ali>,%?acb
ife ?cCall1
?acb=?acb-1
else
?acb=?acb+1
endif
endm
	call	n
if ((?cCall1 eq 0) and (?argl ne 0))
	add	sp,?argl
endif
mpop %?rsl
?rsl=0
?argc= 0
?argl= 0
endm

;;	cProc - define a 'c' procedure
;;
;;	cProc is the procedure definition for procedures.
;;
;;      format:
;;		cProc n,cf,a
;;      where:
;;              n       is the name of the procedure
;;
;;		cf	controls certain definitions, and may be:
;;			    NEAR       proc is to be a near label
;;			    FAR        proc is to be a far  label
;;			    PUBLIC     proc is to be defined as public
;;			    SMALL      call makeframe procedure
;;			    NODATA     dont create prolog code to setup DS
;;			    ATOMIC     don't link stack if not needed
;;				       NODATA must be specified for ATOMIC
;;			    FORCEFRAME Force generation of a frame
;;			    C	       proc is to be a C    procedure
;;			    PLM        proc is to be a PL/M procedure
;;			    PASCAL     proc is to be a PL/M procedure
;;			    WIN        proc is to be a windows procedure
;;			    NONWIN     proc isn't to be a windows procedure
;;
;;              a       is a list of registers that are to be saved whenever
;;                      the procedure is invoked.
;;
;;			makeframe procedure:   If small is specified, then
;;                      the "makeframe procedure" is invoked instead of
;;                      generating normal prologues/epilogues
;;
;;			A call is performed to the makeframe procedure.  The
;;                      call is followed by two bytes.  the first byte is the
;;                      number of locals to allocate for the frame, the second
;;			is the number of bytes of parameters.  The makeframe
;;			procedure will in turn call the cProc routine at the
;;			address following the data bytes.  When the cProc is
;;                      finished, it will do a near return to the makeframe
;;                      procedure to clean up the frame and exit.
;;
;;			Note that register parameters and makeframe are
;;                      incompatible and cannot be used together.
;;
;;			The makeframe procedure will save SI, DI, and also
;;			DS if a far procedure.	These registers will be
;;                      removed from the autosave list if specified.

cProc macro n,cf,a
if ?cpd
?utpe
endif
?cpd=1
???=0
?argc=0
?ba=0
?po=0
?pu=0
?ia=0
?adj=4
?rp=0
?uf=0
?wfp=?WIN
?ff=0
?pas=0
?pcc=?PLM
ifnb <a>
?ri ?pas,<a>
endif
?pc=sizec
?nd=?nodata1
?nx=0
irp x,<cf>
ifidn <x>,<FAR>
?pc=1
endif
ifidn <x>,<NEAR>
?pc=0
endif
ifidn <x>,<PUBLIC>
?pu=1
endif
ifidn <x>,<SMALL>
?uf=1
endif
ifidn <x>,<DATA>
?nd=0
endif
ifidn <x>,<NODATA>
?nd=1
endif
ifidn <x>,<ATOMIC>
?nx=1
endif
ifidn <x>,<FORCEFRAME>
?ff=1
endif
ifidn <x>,<C>
?pcc=0
endif
ifidn <x>,<PLM>
?pcc=1
endif
ifidn <x>,<PASCAL>
?pcc=1
endif
ifidn <x>,<WIN>
?wfp=1
endif
ifidn <x>,<NONWIN>
?wfp=0
endif
endm
if ?pcc
?PLMPrevParm=0
.xcref
.xcref ?PLMParm0
.cref
?PLMParm0 macro arg
purge ?PLMParm0
endm
endif
.xcref
.xcref ?CC&n
.cref
?CC&n=?pcc
if (?nx eq 1) and (?nd eq 0)
?nx = 0
??error <ATOMIC specified without NODATA - ATOMIC ignored>
endif
if ?pc
if ?wfp
ife ?nx
?ia=2
?pas = ?pas and (not ?ds)
endif
endif
?adj=?adj+2
else
?wfp=0
endif
?pas = ?pas and (not (?sp+?cs+?ss))
if ?uf
?pas = ?pas and (not (?bp+?si+?di))
endif
ife ?pcc
?pg <_&n>,%?pu,%?pc,%?pas,%?wfp,<n>,%?pcc
else
?pg <n>,%?pu,%?pc,%?pas,%?wfp,<n>,%?pcc
endif
endm

;;      ?pg - generate begin and nested macros for current procedure
;;
;;      format:
;;		?pg n,p,c,a,w,nnu,cc
;;      where:
;;              n       is the name of the procedure
;;              p       is the public flag
;;              c       is the class definition for the procedure
;;              a       is an enumerated list of registers to save
;;                      at entry and restore at exit
;;              w       true if a far windows procedure
;;		nnu	procedure name without any underscore
;;		cc	calling convention (C or PL/M)
;;
;;
;;      local stack allocation will be forced to an even byte count to
;;      maintain stack word alignment.

?pg macro n,p,c,a,w,nnu,cc
.xcref
if ?uf
if ?nd
??error <NODATA encountered in &n - user frame ignored>
?uf=0
endif
endif
.xcref cBegin
cBegin macro g
.xcref
if cc
uconcat <?PLMParm>,%?PLMPrevParm,%?po
endif
if ?uf
if ?rp
??error <parmR encountered in &n - user frame ignored>
?uf=0
endif
endif
?pg1 <n>,c,a,%?po,w,%?uf,%?nd,%?rp,cc
?cpd=0
?argc=0
?ba=1
???=(???+1) and 0fffeh
if p
public n
endif
ife c
n proc near
else
n proc far
endif
ife cc
nnu equ n
endif
ifidn <g>,<nogen>
if ???+?po+a+?rp
??_out <cBegin - possible invalid use of nogen>
endif
else
if ?uf
?mf c,%???,%?po
mpush a
else
if w
ife ?nd
	mov	ax,ds
	nop
endif
ife ?nx
ife ?DOS5
	inc	bp
endif
	push	bp
	mov	bp,sp
	push	ds
else
if ?ff+???+?po+?rp
	push	bp
	mov	bp,sp
endif
endif
ife ?nd
	mov	ds,ax
endif
else
if ?ff+???+?po+?rp
	push	bp
	mov	bp,sp
endif
endif
if ?rp
?uf=0
rept ?rp
uconcat mpush,,?rp,%?uf
?uf=?uf+1
endm
endif
if ???
if ?chkstk1
ifdef ?CHKSTKPROC
?CHKSTKPROC %???
else
	mov	ax,???
ife cc
	call	_chkstk
else
	call	chkstk
endif
endif
else
	sub	sp,???
endif
endif
mpush a
endif
ifdef ?PROFILE
if c
	call	StartNMeas
endif
endif
endif
.cref
purge cBegin
endm
.xcref ?utpe
?utpe macro
??error <unterminated procedure definition: "&n">
endm
.cref
endm

;;      ?pg1 - generate end macro for current procedure
;;
;;      format:
;;		?pg1 n,c,a,o,w,f,d,r,cc
;;      where:
;;              n       is the name of the procedure
;;              c       is the class definition for the procedure
;;              a       is an enumerated list of registers to save
;;                      at entry and restore at exit
;;              o       is the number of bytes of paramteres to remove at exit
;;              w       true if a far windows procedure
;;              f       is 1 if to use the user's makeframe procedure
;;		d	is 1 if NODATA procedure
;;              r       number of register parameters
;;		cc	calling convention (C or PL/M)

?pg1 macro n,c,a,o,w,f,d,r,cc
.xcref
.xcref cEnd
cEnd macro g
.xcref
?ba=0
ifidn <g>,<nogen>
if o+a+r
??_out <cEnd - possible invalid use of nogen>
endif
else
ifdef ?PROFILE
if c
call StopNMeas
endif
endif
mpop a
if f
	db	0c3h
else
if w
ife ?nx
if (?TF eq 0) or (???+?rp)
	lea	sp,(-2)[bp]
endif
	pop	ds
	pop	bp
ife ?DOS5
	dec	bp
endif
else
if (?TF eq 0) or (???+?rp)
	mov	sp,bp
endif
if ???+?po+?rp
	pop	bp
endif
endif
else
if ?ff+???+?po+?rp
if (?TF eq 0) or (???+?rp)
	mov	sp,bp
endif
	pop	bp
endif
endif
ife cc
	ret
else
	ret	o
endif
endif
endif
n endp
.cref
purge cEnd
endm
.cref
endm

;	assumes is a macro that will set up the assumes for a segment
;	or group created with the createSeg macro.  If the assumed
;	value passed in isn't known, then a normal assume is made.
;
;       usage:
;               assumes s,g
;
;       where:
;               s       is the register to make the assumption about
;               g       is the value to assume is in it

assumes macro s,ln
ifdef MS_STARTUP
ifidn <code>,<ln>
assume s&:_TEXT
exitm
elseifidn <CODE>,<ln>
assume s&:_TEXT
exitm
elseifidn <data>,<ln>
assume s&:dgroup
exitm
elseifidn <DATA>,<ln>
assume s&:dgroup
exitm
endif
endif
ifndef ln&_assumes
assume s:ln
else
ln&_assumes s
endif
endm

;	createSeg is a macro that sets up a segment definition and
;	a logical name for that segment.  The logical name can be
;       used to enter the segment, but it cannot be used for anything
;       else.
;
;       usage:
;		createSeg n,ln,a,co,cl,grp
;       where:
;               n       is the physical name of the segment
;               ln      is the name it is to be invoked by
;               a       is the alignment, and is optional
;               co      is the combine type, and is optional
;               cl      is the class, and is optional
;               grp     is the name of the group that contains this segment

createSeg macro n,ln,a,co,cl,grp
ifnb <cl>
n segment a co '&cl'
else
n segment a co
endif
n ends
?cs1 <ln>,<n>
ifnb <grp>
grp group n
?cs3 <ln>,<grp>
ln&OFFSET equ <offset grp:>
ln&BASE equ <grp>
else
?cs3 <ln>,<n>
ln&OFFSET equ <offset>
ln&BASE equ <n>
endif
endm
addseg macro grp,seg
.xcref
.xcref grp&_add
.cref
grp&_add macro s
grp&_in <seg>,s
endm
.xcref
.xcref grp&_in
.cref
grp&_in macro sl,s
ifb <s>
grp group sl
else
grp&_add macro ns
grp&_in <sl,s>,ns
endm
endif
endm
endm
defgrp macro grp,ln
endm
?cs1 macro ln,n
.xcref
.xcref ln&_sbegin
.cref
ln&_sbegin macro
?cs2 <ln>,<n>
n segment
.xcref
.xcref ?mf
.cref
?mf macro c,l,p
if c
	extrn	n&_FARFRAME:near
	call	n&_FARFRAME
else
	extrn	n&_NEARFRAME:near
	call	n&_NEARFRAME
endif
	db	l shr 1
	db	p shr 1
endm
endm
endm
?cs2 macro ln,n
.xcref
.xcref sEnd
.cref
sEnd macro arg
n ends
purge ?mf
purge sEnd
endm
endm
?cs3 macro ln,n
.xcref
.xcref ln&_assumes
.cref
ln&_assumes macro s
assume s:&n
endm
endm
.xcref
.xcref sBegin
.cref

;	sBegin is the macro that opens up the definition of a segment.
;	The segment must have already been defined with the createSeg
;       macro.
;
;       usage:
;		sBegin ln
;
;       where:
;               ln      is the logical name given to the segment when
;                       it was declared.

sBegin macro ln
ln&_sbegin
endm

  ;	Define all segments that will be used.	This will allow the
  ;	assume and groups to be set up at one given place, and also
  ;	allow quick changes to be made
  ;
  ;	createSeg name,logname,align,combine,class,group

ife ?DF
createSeg _TEXT,Code,word,public,CODE
ife ?nodata1
createSeg _DATA,Data,word,public,DATA,DGROUP
defgrp DGROUP,Data
endif
if ?chkstk1
ifndef ?CHKSTKPROC
externp <chkstk>
endif
endif
endif

;       errnz exp - generate error message if expression isn't zero
;
;	The errnz will generate an error message if the expression "exp"
;	does not evaluate to zero.  This macro is very useful for testing
;       relationships between items, labels, and data that was coded into
;       an application.
;
;                  errnz   <offset $ - offset label>   ;error if not at "label"
;                  errnz   <eofflag and 00000001b>     ;eofflag must be bit 0
;
;	For expressions involving more than one token, the angle brackets
;       must be used.
;
;	The macro is only evaluated on pass 2, so forward references may be
;       used in the expression.

errnz macro x
ifnb <x>
.errnz (x),<x>
endif
endm
errnz1 macro x1,x2
= *errnz* x1 = x2
.err
endm

;       errn$ label,exp - generate error message if label (exp) <> $
;
;	The errnz will generate an error message if the label and "exp"
;       does not evaluate to the current value of the location counter.
;	This macro is very useful for testing relationships between
;       labels and the location counter that was coded into an application.
;
;       examples:  errn$   label        ;error if not at "label"
;                  errn$   label,+3     ;error if not three bytes from "label"
;                  errn$   label,-3     ;error if not three bytes past "label"
;
;	If no "exp" is given, it is the same as specifying 0
;
;	The macro is only evaluated on pass 2, so forward references may be
;       used in the expression.

errn$ macro l,x
errnz <offset $ - offset l x>
endm

;;	If profile has been specified, declare the profile routines
;;	to be external and far.  It would be best if this could be done
;;	when the call is actually made, but then the fix-up would be
;;	generated as segment-relative.

ifdef ?PROFILE
externFP <StartNMeas,StopNMeas>
endif

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


; Extra macros for the c-runtime package
;
; Macro for calling another run-time-library function.
; Does a PUSH CS/CALL NEAR in compact/large models, except
; for QuickC.		

callcrt MACRO funcname
ifdef _QC2
call funcname
else
if sizeC
push cs
call near ptr (funcname)
else
call funcname
endif
endif
ENDM
.cref

⌨️ 快捷键说明

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