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

📄 cmacros.inc

📁 C-编译器的设计文档与源代码下载,1. 具有比较友好的GUI界面(仿照了我自己正在用的emacs); 2. 语法支持比较全面(毕竟是C-
💻 INC
📖 第 1 页 / 共 3 页
字号:
comment $
cmacros - assembly macros for interfacing to hhls
(C)Copyright Microsoft Corp. 1984-1993
$

.xcref
??CM_Paste macro arg1:req, arg2:req
exitm <arg1&arg2>
endm

;	??_out	- output given message to the console unless ?QUIET has
;	been specified.
;
;	usage:
;		??_out	<t>
;
;	where:
;		<t> is the message to output
.xcref ??_out
??_out macro t
ifndef ?QUIET
%out t
endif
endm

;	outif - output msg if name is non-zero.  if name is undefined,
;	set name = 0, else set name to the default value.
;
;	usage:
;		outif	name,defval,onmsg,offmsg
;	where:
;		name	name of symbol
;		defval	default value to give symbol if not defined
;			if blank, then 0 will be used
;		onmsg	text to display if symbol is non-zero
;		offmsg	test to be displayed if symbol is zero

outif macro name,defval,onmsg,offmsg
ifndef name
ifb <defval>
name=0
else
name=defval
endif
endif
if name
name=1
ifnb <onmsg>
??_out <! onmsg>
endif
else
ifnb <offmsg>
??_out <! offmsg>
endif
endif
endm

;	??error - output msg and generate an assembly time error
;
;	usage:
;		??error <t>
;	where:
;		t	is the text to be output

.xcref ??error
??error macro msg
%out e r r o r ----- msg
.err e r r o r ----- msg
endm
.xcref ASMpass
.xcref memS,memM,memL,memC,memH,memMOD,sizec,sized
ASMpass=1
ifdef ?SMALL
memS=1
endif
ifdef ?MEDIUM
memM=1
endif
ifdef ?COMPACT
memC=1
endif
ifdef ?LARGE
memL=1
endif
ifdef ?HUGE
memH=1
endif
??_out <cMacros Version 5.32 - Copyright (c) Microsoft Corp. 1984-1993>
outif memS,0,<Small Model>
outif memM,0,<Medium Model>
outif memL,0,<Large Model>
outif memC,0,<Compact Model>
outif memH,0,<Huge Model>
memMOD= memS + memM + memL + memC + memH
if memMOD ne 1
if memMOD eq 0
memS = 1
outif memS,0,<Small Model>
else
??error <more than 1 memory model selected>
endif
endif
sizec= memM + memL + memH
sized= memL + memC + (memH*2)
outif ?DF,0,<No segments or groups will be defined>
outif ?TF,0,<Epilog sequences assume valid SP>
outif ?WIN,1,<Windows support>
if ?WIN eq 1
outif ?PLM,1,<>
else
outif ?PLM,1,<PL/M calling convention>
endif
ifndef ?NODATA
?nodata1=0
else
?nodata1=1
??_out <! NODATA module>
endif
ifndef ?CHKSTK
?chkstk1=0
else
?chkstk1=1
ifdef ?CHKSTKPROC
??_out <! Private stack checking enabled>
else
??_out <! Stack checking enabled>
endif
endif
ifndef DOS5
?DOS5=0
else
?DOS5=1
??_out <! DOS5 module>
endif
ifdef ?PROFILE
??_out <! Native profiling enabled>
endif
;;	Initialize all symbols used in the macros.  Theses symbols will not be
;;      included in any cross reference listing.
.xcref ?n,?ax,?ah,?al,?bx,?bh
.xcref ?bl,?cx,?ch,?cl,?dx,?dh
.xcref ?dl,?si,?di,?es,?ds,?bp
.xcref ?sp,?ss,?cs
.xcref ?rsl,?cpd,?argl,?argc,?ba
.xcref ?acb,???,?po
.xcref ?pas,?pc
.xcref uconcat,mpush,mpop
.xcref ?ri,?pp,?pp1,?al1
.xcref ?ad,?ap,?atal,?dd,?dd1,?dd2
.xcref ?pg,?pg1,?aloc,?cs1,?cs2
.xcref ?DF,?TF,?ff,?PLM,?WIN,?ia,?pu,?adj
.xcref ?uf,?rp,?nx,?nd,?nodata1,?chkstk1,?DOS5
.xcref ?wfp,arg,cCall,cProc,assumes,?cs3,?cs2,?cs1
.xcref defgrp,addseg,createSeg
.xcref save,outif,errnz,errn$,errnz1
.xcref ?PLMPrevParm,?gcc
.xcref ?cCall1,?pcc
?rsl    =       0           ;;0 = no register to save
?cpd    =       0           ;;<> 0 if in a procedure definition
?argl   =       0           ;;length of arguments pushed on stack
?argc   =       0           ;;# of arguments so far
?ba     =       0           ;;<>0 if in a procedure (xbegin)
?acb    =       0           ;;number of arguments to a call
???     =       0           ;;byte count of local storage
?po     =       0           ;;byte count of parameters
?pas    =       0           ;;autosave value for procedure
?pc     =       0           ;;class of a procedure (near/far)
?ia     =       0           ;;no adjustment
?pu     =       0           ;;public flag for some macros
?adj    =       0           ;;initial define for .xcref
?rp     =       0           ;;count of register parameters
?uf     =       0           ;;user's frame code specified
?nd	    =	    0			;;NODATA keyword specified
?nx	    =	    0			;;ATOMIC keyword specified
?wfp    =       0           ;;window far procedure
?ff     =       0           ;;forceframe keyword specified
?dd2	=	    0			;;used for globalx and staticx
?cCall1 =	    0			;;used for cCalls
?pcc	=	    ?PLM		;;procedure calling convention
?PLMPrevParm =	0			;;Used in parameter processing
.xcref ?casen
if1
?casen = 0
endif
?n = 0000000000000000b
?ax = 0000000000000011b
?ah = 0000000000000001b
?al = 0000000000000010b
?bx = 0000000000001100b
?bh = 0000000000000100b
?bl = 0000000000001000b
?cx = 0000000000110000b
?ch = 0000000000010000b
?cl = 0000000000100000b
?dx = 0000000011000000b
?dh = 0000000001000000b
?dl = 0000000010000000b
?si = 0000000100000000b
?di = 0000001000000000b
?es = 0000010000000000b
?ds = 0000100000000000b
?bp = 0001000000000000b
?sp = 0010000000000000b
?ss = 0100000000000000b
?cs = 1000000000000000b
.cref

;;      uconcat - unconditionally generate a statement from a field
;;      of given parameters
;;
;;      usage:
;;		uconcat  a,b,c,d,e,f,g
;;
;;      where:
;;              a,b   are concatenated for field 1
;;              c,d   are concatenated for field 2
;;		e,f,g are concatenated for field 3

uconcat macro a,b,c,d,e,f,g
a&b c&d e&f&g
endm

;;      mpush pushes multiple registers onto the stack according to
;;      a register specification.
;;
;;      format:
;;              mpush   r
;;
;;      where:
;;              r       is a numeric expression returned from ?ri
;;                      or any other valid register expression

mpush macro r
irp x,<ax,bx,cx,dx,si,di,es,ds,bp,sp,ss,cs>
%if (r and ??CM_Paste(?,x))
push	x
endif
endm
endm

;;      mpop pops multiple registers from the stack according to
;;      a register specification.
;;
;;      format:
;;              mpop    r
;;
;;      where:
;;              r       is a numeric expression returned from ?ri
;;                      or any other valid register expression

mpop macro r
irp x,<cs,ss,sp,bp,ds,es,di,si,dx,cx,bx,ax>
%if (r and ??CM_Paste(?,x))
pop	x
endif
endm
endm

;;      save - flag that the indicated registers are to be saved/restored
;;
;;	A flag is created which indicates which registers are to be saved
;;	when the cCall macro is invoked, and then restored after the call.
;;
;;      usage:
;;              save    <r>
;;
;;      where  r  is the list of registers to save, which may be:
;;
;;		register     saves
;;		   AX	      AX
;;		   AH	      AX
;;		   AL	      AX
;;		   BX	      BX
;;		   BH	      BX
;;		   BL	      BX
;;		   CX	      CX
;;		   CH	      CX
;;		   CL	      CX
;;		   DX	      DX
;;		   DH	      DX
;;		   DL	      DX
;;		   SI	      SI
;;		   DI	      DI
;;		   ES	      ES
;;		   DS	      DS
;;		   BP	      BP
;;
;;		  none	    nothing
;;
;;      the macro generates a value for the variable ?rsl

save macro r
?rsl=0
?ri ?rsl,<r>
endm

;;      ?ri - or register indexes to variable
;;
;;      ?ri is a macro that examines the passed argument list and computes
;;      a register index variable.
;;
;;	The values ORed with the variable are:
;;
;;              ?n       equ     0000000000000000b;
;;		?AX	 equ	 0000000000000011b;
;;		?AH	 equ	 0000000000000001b;
;;		?AL	 equ	 0000000000000010b;
;;		?BX	 equ	 0000000000001100b;
;;		?BH	 equ	 0000000000000100b;
;;		?BL	 equ	 0000000000001000b;
;;		?CX	 equ	 0000000000110000b;
;;		?CH	 equ	 0000000000010000b;
;;		?CL	 equ	 0000000000100000b;
;;		?DX	 equ	 0000000011000000b;
;;		?DH	 equ	 0000000001000000b;
;;		?DL	 equ	 0000000010000000b;
;;		?SI	 equ	 0000000100000000b;
;;		?DI	 equ	 0000001000000000b;
;;		?ES	 equ	 0000010000000000b;
;;		?DS	 equ	 0000100000000000b;
;;		?BP	 equ	 0001000000000000b;
;;		?SP	 equ	 0010000000000000b;
;;		?SS	 equ	 0100000000000000b;
;;		?CS	 equ	 1000000000000000b;
;;      usage:
;;              ?ri n,<r>
;;      where:
;;              n       is the variable to contain the new index value
;;              r       is the register list

?ri macro n,r
irp x,<r>
%ifdef ??CM_Paste(?,x)
%n=n or ??CM_Paste(?,x)
endif
endm
endm

;;      parmx - generate reference to parameter(s) on the stack
;;
;;	An equate is generated for addressing a paramter(s)
;;      on the stack for the current procedural frame.
;;
;;	An error message is generated if there isn't a current frame.
;;
;;      usage:
;;              parmx   n
;;      where:
;;              x       is the type of the argument(s)  b=byte, w=word, d=dword
;;              n       is the name(s) to be given the parameter(s).
;;
;;	Bytes are considered to be two bytes long for alignment.
;;
;;	The parmd form of the macro generates three equates:
;;
;;              name       -    for accessing the parameter as a double word
;;              off_name   -    for accessing the offset  (lsw) of the parameter
;;              seg_name   -    for accessing the segment (msw) of the parameter

.xcref
.xcref parmB,parmW,parmD,parmQ,parmT,parmCP,parmDP,parmH
.cref
parmB macro n
?pp <n>,<byte>,2,1
endm
parmW macro n
?pp <n>,<word>,2,2
endm
parmD macro n
ife ?pcc
irp x,<n>
?pp <&&x>,<dword>,0,4
?pp <off_&&x>,<word>,2,2
?pp <seg_&&x>,<word>,2,2
endm
else
irp x,<n>
?pp <seg_&&x>,<word>,2,2
?pp <off_&&x>,<word>,2,2
?pp <&&x>,<dword>,0,4
endm
endif
endm
parmH macro n
?pp <n>,<word>,4,2
endm
parmQ macro n
?pp <n>,<qword>,8,8
endm
parmT macro n
?pp <n>,<tbyte>,10,10
endm
if sizec
parmCP macro n
parmD <n>
endm
else
parmCP macro n
parmW <n>
endm
endif
if sized
parmDP macro n
parmD <n>
endm
else
parmDP macro n
parmW <n>
endm
endif

;;      ?pp is the generalized parameter definition macro
;;
;;      usage:
;;              ?pp m,t,l,s
;;
;;      where:
;;              n       is the name(s) of the parameters
;;              t       is the type (word, dword)
;;              l       is the length to update parameter byte count by
;;              s       is the internal typing size

?pp macro n,t,l,s
if ?cpd
.xcref
irp x,<n>
%.xcref ??CM_Paste(?t_,x)
%??CM_Paste(?t_,x)=s
ife ?pcc
?pp1 x,<t>,,,%(?po+?adj)
?po=?po+l
else
?PLMPrevParm=?PLMPrevParm+1
?po=?po+l
?pp1 x,<t>,%?po,%?adj,,%?PLMPrevParm,%(?PLMPrevParm-1)
endif
endm
.cref
else
??error <parm(s) "&n" declared outside proc def>
endif
endm

;;	?pp1 is the macro that generates the text equate for the
;;	parameter.  Two options exist, one for the C calling
;;      convention where the last parameter was the first pushed onto
;;	the stack ('C' convention), and one for the PL/M calling
;;      convention where the first parameter was the first
;;      pushed (also the same as ms-pascal).
;;
;;	The text generated will be of one of two forms:
;;
;;		name equ (type ptr [bp+(adj+offset)]) for C
;;           or
;;		name equ (type ptr [bp+adj+?po-offset]) for PL/M
;;
;;
;;	For C, since parameters are pushed first last, the offset
;;      plus the adjust will point to the correct parameter.
;;
;;	For PL/M, since parameters are pushed first first, the offset
;;	of a parameter is much more complicated.  A known portion of
;;      the offset can be computed when the text equate is generated.
;;
;;	What is known is the number of garbage bytes between BP and
;;      the nearest parameter (in this case the last parameter), and
;;      also how many bytes of parameters have preceeded this parameter.
;;
;;	What is unknown is how many total bytes of parameters there will
;;      be, which affects all the generated text equates since the offset
;;      from bp must be determined at some point.
;;
;;	Well, the offset from BP can be computed with one variable if
;;      the following is remembered:
;;
;;          the offset of any parameter from the first parameter is always
;;          the current parameter offset (?po).
;;
;;	With this in mind, you just have to figure out where the first
;;      parameter is, which is:
;;
;;              bp + garbage adjustment + distance to first parameter
;;         or
;;              bp + ?adj + ?po
;;
;;	This implies that any parameter can be defined as:
;;
;;              bp + ?adj + ?po -%?po
;;
;;	Make any sense?
;;
;;	For PL/M, a chain of self-purging macros will be generated
;;	which will pass the evaluated ?po to any previous incarnation
;;	of the macro.  This will allow the text equate to be generated
;;	with the actual offset instead of the symbolic ?po.
;;
;;
;;      usage:
;;		?pp1	n,t,o,a,b,cpc,ppc
;;
;;      where:
;;              n    is the name to be given the equate
;;              t    is the type (byte, word, dword)
;;              o    is the offset from the first parameter
;;              a    is the adjustment
;;              b    is the adjustment plus the offset from the first parameter
;;		cpc  is the number of parameters so far
;;		ppc  is cpc - 1

?pp1 macro n,t,o,a,b,cpc,ppc
ife ?pcc
n equ (t ptr [bp][+b])
else
.xcref
.xcref ?PLMParm&cpc
.cref
?PLMParm&cpc macro po
uconcat <n>,,<equ>,,<(t ptr [bp][+>,%(a+po-o),<])>
?PLMParm&ppc po
purge ?PLMParm&cpc
endm
endif
endm

;;	parmR - register parameter
;;
;;	parmR is the macro used for generating register parameters.
;;	The space allocated for the register parameters will be
;;      the ?ia (interface adjust) area which is between the  old
;;	BP and the first parameter.  Normally this is empty (?ia=0),
;;      or has the saved ds for a windows far procedure.
;;
;;	Byte and dword register parameters will be allowed.
;;
;;      usage:
;;		parmR	n,r,r2
;;      where:
;;              n       is the name of the parameter
;;              r       is the register it is in
;;              r2      is the offset register if a dword

ifndef ?NOPARMR
.xcref
.xcref ?pr,parmR
.cref
parmR macro n,r,r2
?pr n,r,r2,%?rp,%(?ia+2)
endm

  ;;	?pr - register parameter
  ;;
  ;;	?pr is the actual macro for generating the equates for
  ;;	register parameters.
  ;;
  ;;	usage:
  ;;		parmR	n,r,r2,i,o
  ;;	where:
  ;;		n	is the name of the parameter
  ;;		r	is the register it is in
  ;;		r2	is the offset register if a dword
  ;;		i	is the index of the ?rp to generate
  ;;		o	is the offset from bp where the parm will be

?pr macro n,r,r2,i,o
.xcref
ifnb <r2>
parmR seg_&n,r
parmR off_&n,r2
n equ (dword ptr [bp][-o-2])
.xcref ?t_&n
?t_&n=4
else
.xcref ?rp&i
?rp&i=0
ifdef ?&r
?rp&i=?&r
endif
if ??? or (?cpd eq 0) or (?rp&i eq 0)
??error <invalid parmR encountered: &n,&r>
exitm
endif
n equ (word ptr [bp][-o])
.xcref ?t_&n
?t_&n=2
irp x,<bh,ch,dh,bl,cl,dl,ah,al>
%if ??CM_Paste(?,x) eq ??CM_Paste(?,r)
n equ (byte ptr [bp][-o])
%??CM_Paste(?t_,n)=1
exitm
endif
endm
?ia=?ia+2
?rp=?rp+1
endif
.cref
endm
endif

;;      localx - generate reference to a local variable on the stack
;;
;;	An equate is generated for addressing a local variable
;;      on the stack for the current procedural frame.
;;
;;      usage:
;;              localx    n
;;      where:
;;              x       is the type b=byte, w=word, d=dword, v=variable size
;;              n       is the name(s) to be given the variable(s).
;;
;;	Bytes are considered to be two bytes long for alignment reasons
;;
;;	The locald form of the macro generates three equates:
;;
;;              name       -    for accessing the variable as a double word
;;              off_name   -    for accessing the offset  (lsw) of the variable
;;              seg_name   -    for accessing the segment (msw) of the variable

.xcref
.xcref localB,localW,localD,localQ,localT,localCP,localDP,localV
.cref
localB macro n
?aloc <n>,<byte ptr>,1,1,0
endm
localW macro n
?aloc <n>,<word ptr>,2,2,1
endm
localD macro n
irp x,<n>
?aloc <seg_&&x>,<word ptr>,2,2,1
?aloc <off_&&x>,<word ptr>,2,2,1
?aloc <&&x>,<dword ptr>,0,4,1
endm
endm
localQ macro n
?aloc <n>,<qword ptr>,8,8,1
endm
localT macro n
?aloc <n>,<tbyte ptr>,10,10,1
endm
if sizec
localCP macro n
localD <n>
endm
else
localCP macro n
localW <n>
endm
endif
if sized
localDP macro n
localD <n>
endm
else
localDP macro n
localW <n>
endm
endif
localV macro n,a
?aloc <n>,,%(a),0,1
endm

;;      ?aloc is the macro that actually allocates local storage.
;;      it is only invoked by the localx macros.
;;
;;      usage:
;;              ?aloc  n,t,l,s,a
;;      where:
;;              n      is a list of names of local variable of the
;;                      given type.
;;              t       is the text string for the given variable
;;                      and is one of:
;;                          word  ptr
;;                          dword ptr
;;                          byte  ptr
;;                      or alternatively left blank for variable size
;;                      allocations (no implicit type).
;;              l       is the size of the variable in bytes

⌨️ 快捷键说明

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