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

📄 cmacros.new

📁 mas for 8086 microprocessor
💻 NEW
📖 第 1 页 / 共 3 页
字号:
COMMENT $

CMACROS - assembly macros for interfacing to HLL

(C)Copyright Microsoft Cor. 1990

$

; Revision History
;	6.0	Initial Release of cmacros for MASM 6.0
;

COMMENT $

; Note:  There are some differences between this version of CMACROS
;	and previous releases.  The most signification is the fact
;	that locals and parameter names are now scoped to the body
;	of a procedure.  To help ease this problem we have introduced
;	a new directive cRet. This means that the following transformation
;	can occur on your source to deal with parameters no referenced
;	in the body of a procedure
;
;	cProc				cProc
;	locals,parms			locals,parms
;	cBegin				cBegin
;	....				...
;	cEnd				cRet
;	error code referencing 		error code referencing
;		locals and parms		locals and params
;					cEnd <nogen>
;
;	The major reason for making locals and parameters scoped was
;	the percieved benifit of error checking for defined labels in
;	the procedure and the addition of codeView information on locals
;	and parameters for functions.

$
.xcref					; Get rid of alot of symbols

;	??_out - output the given message to the console unless ?QUIET
;		has been specified
;
;	usage:
;		??_out <t>
;	where:
;		<t> is the message to output

??_out macro t
 ifndef ?QUIET
  echo 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 symobl if not defined.
;			if blank, then 0 will be used
;	onmsg	text to display if symbol is non-zero
;	offmsg	text to display if symbol is zero
;

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


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

??error macro msg
 echo e r r o r ------ msg		;; to console
 .err e r r o r ------ msg		;; forced error by assembler
endm

??_out <cMacros Version 6.00 - 1/1/91>
??_out <Copyright (C) Microsoft Corp. 1990-1991. All rights reserved.>

;
; Determine the memory model for cmacros.  Default to small if
;	no other model has been specified.
;

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


outif	memS,0,<Small Model>
outif	memM,0,<Medium Model>
outif	memC,0,<Compact Model>
outif	memL,0,<Large Model>
outif	memH,0,<Huge Model>

memMOD = memS + memM + memL + memC + memH
if memMOD ne 1
 if memMOD eq 0
  memS=1				; Assume small model
  outif	memS,0,<Small Model>
 else
  ??error <must have only 1 memory model selected>
 endif
endif

sizec = memM + memL + memH		; Large Code models
sizeC = sizec
sized = memC + memL + memH		; Large Data models
sizeD = sized

;
;  Inform user of any other options selected
;

outif	?DF,0,<No segments or groups will be defined>
outif	?DFDATA,0,<No data segments will be defined>
outif	?DFCODE,0,<No code segments will be defined>
outif	?TF,0,<Epilogue sequences will assume valid SP>
outif	?WIN,1,<Windows support>
outif	?COW,0,<Character Windows support>
outif	?PLM,1,<PL/M calling convention>
outif	?NOATOMIC,0,<ATOMIC calling convention>
outif	?NODATA,0,<NODATA module>

ifdef ?CHKSTK
 ifdef ?CHKSTKPROC
  ??_out <! Private stack checking enabled>
 else
  ??_out <! Stack checking enabled>
 endif
else
 ?CHKSTK = 0
endif

ifndef ?DOS5
?DOS5 = 0
endif

;
; Setup some local variables to the Cmacros package
;

??CM_state = 0			; 0 - inactive, 1-cProc, 2-cBegin, 
??CM_RegSaveList textequ <>	; List of saved registers
??CM_ArgList textequ <>

;
;	This function is used to paste together two text items to
;	get a third text item.
;

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

;
;	This function is used to create a text macro containning the
;	n-th local to a fuction definition.
;

??CM_addLocal macro arg1:req
 ??CM_Paste(??CM_local, %??CM_localCount) textequ <LOCAL arg1>
 ??CM_localCount = ??CM_localCount + 1
endm

;
;	This function is used to create a text macro containning the
;	n-th parameter to a function definition
;

??CM_addParm macro arg1:req
 if ??CM_argCount EQ 20
  .err <CMACROS.INC: Cannot have more than 20 arguements to a procedure>
 endif
 ??CM_Paste(??CM_arg, %??CM_argCount) textequ <, arg1>
 ??CM_argCount = ??CM_argCount + 1
endm

;
;	This macro creates the prologue code for a cmacro defined function.
;	
;	Prologue sequences
;

cPrologue macro procname, flags, cbParms, cbLocals, reglist, userparms

  ?ba=0 				;;not in a procedure
  ?pu=0 				;;initial public setting
  ?ia=0 				;;no special prolog/epilog
  ?rp=0 				;;no register parameters
  ??CM_UserDoesFrame=0			;;don't use makeframe
  ?ff=0 				;;don't force frame setup
  ?pas=0				;;process register save list
  ?pcc=?PLM				;;calling convention (C or PL/M)

  
  
  ;;
  ;; Look at all of the user parameters and make appropriate decisions
  ;;

  for x,<userparms>
    ifdef ??CM_Paste(??_cproc_, x)
      ??CM_Paste(??_cproc_, x)
    else
      ??error <e r r o r - unknown keyword x>
      .err
    endif
  endm
  
  ;;
  ;; Now start some error checking
  ;;

  if (??CM_Atomic eq 1) and (??CM_NoData eq 0) ;;ATOMIC requires NODATA
    ??error <ATOMIC specified without NODATA - ATOMIC ignored>
    ??CM_Atomic = 0				;;clear the ATOMIC keyword
  endif

  if flags AND 020h			;;if a far procedure
    if ??CM_WinFarProc			;;if windows
      ife ??CM_Atomic			;;if not ATOMIC
        ife ?COW			;; COW dos not save DS
	  ?ia=2				;;  adjust locals for saved ds
;	  ?pas = ?pas and (not ?ds)	;;no need for extra save
	endif
      endif
    endif
  else
    ??CM_WinFarProc=0			;;not a far windows procedure
  endif

; ?pas = ?pas and (not (?sp+?cs+?ss))	;;make no sense to save these

  if ??CM_UserDoesFrame				;;don't save these if user frame
;  ?pas = ?pas and (not (?bp+?si+?di))
  endif

  if ??CM_UserDoesFrame				;;if user frame
    if ??CM_NoData
      ??error <NODATA encountered in &n - user frame ignored>
      ??CM_UserDoesFrame=0
    endif
  endif
	
  if ??CM_UserDoesFrame				;;if user frame
   if ?rp				;;If register parameters
    ??error <parmR encountered in &n - user frame ignored>
    ??CM_UserDoesFrame=0
   endif
  endif
   
  ?cpd=0				;;terminate current proc def
    
 ifidn <g>,<nogen>			;;if nogen, then cannot have locals
  if cbLocals + cbParms + ?rp	;;  saved regs, or parmRs
   ??_out <cBegin - possibly invalid use of nogen>
  endif
 else					;;else must generate a frame
   
  ;;
  ;;  Allow the user to specify his own routine which is going to
  ;;	do the frame set-up for this procedure
  ;;
  
  if ??CM_UserDoesFrame		;;if user frame code specified
   ?mf c,cbLocals,%?po		;;  call user's makeframe
   for reg,reglist		;;  save specified registers
    push reg
   endm
  else

   if ??CM_WinFarProc		;;if a far windows procedure
    ife ??CM_NoData		;;if not NODATA,
     mov ax,ds 			;;   then set AX = current ds, and    ;@
     nop			;;   leave room for  MOV AX,1234h     ;@
    endif

    ife ??CM_Atomic		;;if not ATOMIC, far frame must be set
     
     ife ?DOS5 			;;if not DOS5, then set far frame flag
      inc bp			;;  by incrementing the old bp	      ;@
     endif
	      
     push bp							      ;@
     mov bp,sp 						      ;@
	      
     ife ?COW			;; save DS not needed for CW
      push ds							      ;@
     endif
      
    else			;;ATOMIC procedure
	    
     if ?ff+cbLocals+cbParms+?rp	;;if any locals or parameters
      push bp 			;;  then must set frame pointer       ;@
      mov bp,sp			;;  to be able to access them	      ;@
     endif
	      
    endif
	    
    ife ??CM_NoData		;;if not NODATA, then AX should
     mov ds,ax 			;;  have the ds to use		      ;@
    endif
	    
   else				;;not windows.	use standard prolog
	  
    if ?ff+cbLocals+cbParms+?rp		;;if any locals or parameters
     push bp			;;  then must set frame pointer       ;@
     mov bp,sp 		;;  to be able to access them	      ;@
    endif
   endif
    
   if ?rp			;;if parmR's, push them before
    ??CM_UserDoesFrame=0			;;  allocating locals and saving
    rept ?rp			;;  the autosave registers
     uconcat mpush,,?rp,%??CM_UserDoesFrame
     ??CM_UserDoesFrame=??CM_UserDoesFrame+1
    endm
   endif
    
   if cbLocals			;;if locals to allocate
    if ?CHKSTK	 		;;if stack checking enabled
     ifdef ?CHKSTKPROC 		;;if user supplied stack checking
      ?CHKSTKPROC %cbLocals	;;  invoke it with bytes requested
     else
      mov ax,cbLocals		;;invoke default stack checking       ;@
      ife cc
       call _chkstk						      ;@
      else
       call chkstk						      ;@
      endif
     endif
    else			;;no stack checking
     sub   sp,cbLocals	;; allocate any local storage	      ;@
    endif
   endif
  endif
   
  for reg,reglist		;;save autosave registers
   push reg
  endm
 endif				;; No Gen

 ifdef ?PROFILE		;;if profiling enabled
  if c				;;  and a far procedure
   call StartNMeas		;;  invoke profile start procedure    ;@
  endif
 endif
 
 exitm %(cbLocals+?ia)
endm

;
;	This macro will define the epilogue sequences for CMACROS
;	functions.
;
;	Epilog sequences

cEpilog macro procname, flags, cbParms, cbLocals, reglist, userparms
 if ??CM_nogen			;; Nogen the cEnd --
  exitm
 endif

 ?ba=0				;;no longer in a procedure

 ifidn <g>,<nogen>		;;if nogen, then cannot have parmRs
  if a+r+lc 			;;  locals, or saved registers
   ??_out <cEnd - possibly invalid use of nogen>
  endif
 else				;;else must remove the frame
  ifdef ?PROFILE		;;if profiling enabled
   if flags AND 020H		;;  and a far procedure
    call StopNMeas		;;  invoke profile stop procedure
   endif			;;  (doesn't trash DX:AX)
  endif				;; ?PROFILE
  for reg,reglist		;;restore autosaved registers
   pop reg
  endm
  if ??CM_UserDoesFrame		;;if to use the "makeframe" procedure
   db 0c3h 			;;  near return to user's makeframe    @
  else
   if ??CM_WinFarProc		;;if far win proc, use special epilog
    ife ??CM_Atomic		;;if not ATOMIC, bp was pushed
     ife ?COW			;; restore DS not needed for CW
      if (?TF eq 0) or (cbLocals+?rp)	;;if cannot assume valid sp
       lea sp,-2+[bp]		;;  or locals or parmR's, get valid SP @
      endif
      pop ds			;;restore saved ds and bp	       @
     else
      if (?TF eq 0) or (cbLocals+?rp)	;;if cannot assume valid sp
       mov sp,bp
      endif
     endif
     pop BP			;;				       @
     ife ?DOS5			;;if not DOS5, bp was
      dec BP			;;  incremented to mark far frame      @
     endif
    else				;;ATOMIC frame was set up
     if memS32
      leave
     else
      if (?TF eq 0) or (cbLocals+?rp)	;;if cannot assume valid sp
       mov SP,BP 		;;  or locals or parmR's, get valid SP @
      endif
      if cbLocals+cbParms+?rp
       pop BP						      ;@
      endif
     endif
    endif
   else				;;non-windows standard epilog
    if ?ff+cbLocals+cbParms+?rp		;;if any parameters
     if (?TF eq 0) or (cbLocals+?rp)	;;if cannot assume valid SP
      mov SP,BP 		;;  or locals or parmR's, get valid SP;@
     endif
     pop BP							      ;@
    endif
   endif			;; Far Win Proc
   ife flags AND 010H		;;if Pascal calling convention
    ret cbParms			;;  return and remove paramteres      ;@
   else				;;else
    ret 			;;  return 			      ;@
   endif
  endif				;; User makes frame
 endif				;; noGen
endm

;
; cProc - This macro is used to define the start of a procedure in CMACROS.
;
; PARAMETERS:
;    pname   - The name of the procedure to be defined.  This field is
;		required to be present.
;    attribs - This is a list of attributes which may be placed on the
;		function being defined.
;    autoSave - This is an optional list of registers which are to be
;		saved and restored during the prologue/epilogue processing
;


cProc macro pname:REQ, attribs, autoSave

 IF ??CM_state NE 0			;; No nesting of functions allowed
  .err	<CMACROS.INC: Cannot nest procedure definitions>
 endif
 ;
 ;  Setup some state variables to start the procedure definition
 ;
 ??CM_state = 1				;; Set state variable to seen cProc
 ??CM_ProcName EQU <pname>
 ??CM_ProcAutoSave EQU <autoSave>
 ??CM_localCount = 0
 ??CM_argCount = 0
 ??CM_langType EQU <>
 ??CM_WinFarProc=?WIN			;;default far procedure (win or not)
 ??CM_NoData=?NODATA			;;default NODATA flag
 ??CM_Atomic=?NOATOMIC 			;;default is not ATOMIC
 repeat 20				;; Clear all parameter textmacros
  ??CM_Paste(??CM_arg, %??CM_argCount) textequ <>
  ??CM_argCount = ??CM_argCount + 1
 endm
 ??CM_argCount = 0
 
 ife sizec				;; Set the default distance
  dist equ <NEAR>
 else
  dist equ <FAR>
 endif
 
 vis equ <>				;; Set the default visibility
 
 for arg,<attribs>			;; Look at the attribute list
  ifidn <arg>, <FAR>
   dist equ <FAR>
  elseifidn <arg>,<NEAR>
   dist equ <NEAR>
  elseifidn <arg>,<PUBLIC>
   vis equ <PUBLIC>
  elseifidn <arg>,<PRIVATE>
   vis equ <PRIVATE>
  elseifidn <arg>,<LOCAL>		;; Ignore -- only for CRT
  elseifidn <arg>,<PASCAL>
    ??CM_langType equ <PASCAL>
  elseifidn <arg>,<C>
    ??CM_langType equ <C>
  elseifidn <arg>,<WIN>
    ??CM_WinFarProc=1
  elseifidn <arg>,<NOWIN>
    ??CM_WinFarProc=0		
  elseifidn <arg>,<NODATA>
    ??CM_NoData=1
  elseifidn <arg>,<ATOMIC>
    ??CM_Atomic=1
  else
%  .err <CMACROS.INC: cProc -- Unknown arguement '&arg'>
  endif
 endm
 
 option prologue:cPrologue		;; Change to our prologue sequence
 option epilogue:none			;; rets from here on are just rets
	
endm


;

cBegin macro pname

⌨️ 快捷键说明

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