windows-nt/Source/XPSP1/NT/sdktools/masm/asmmac.c
2020-09-26 16:20:57 +08:00

307 lines
5 KiB
C

/* asmmac.c -- microsoft 80x86 assembler
**
** microsoft (r) macro assembler
** copyright (c) microsoft corp 1986. all rights reserved
**
** randy nevin
**
** 10/90 - Quick conversion to 32 bit by Jeff Spencer
*/
#include <stdio.h>
#include <string.h>
#include "asm86.h"
#include "asmfcn.h"
#include "asmctype.h"
/*** macrodefine - define a macro
*
* macrodefine ();
*
* Entry
* Exit
* Returns
* Calls
*/
VOID PASCAL CODESIZE
macrodefine ()
{
checkRes();
if (!symFet ()) {
/* Need to make it */
symcreate (M_DEFINED | M_BACKREF, MACRO);
}
if (symptr->symkind != MACRO)
errorn (E_SDK);
else {
crefdef ();
/* Save ptr to macro entry */
macroptr = symptr;
/* Make param record */
createMC (0);
BACKC ();
do {
SKIPC ();
scandummy ();
} while (PEEKC () == ',');
macroptr->symu.rsmsym.rsmtype.rsmmac.parmcnt = (unsigned char)pMCur->count;
pMCur->count = 0;
localflag = TRUE; /* LOCAL is legal */
swaphandler = TRUE;
handler = HMACRO;
blocklevel = 1;
}
}
/*** macrobuild - build body of macro
*
* macrobuild ();
*
* Entry
* Exit
* Returns
* Calls
*/
VOID PASCAL CODESIZE
macrobuild ()
{
#ifdef BCBOPT
if (fNotStored)
storelinepb ();
#endif
if (localflag) { /* Still legal, check */
getatom ();
if (fndir () && optyp == TLOCAL) {
/* Have LOCAL symlist */
BACKC ();
do {
SKIPC ();
scandummy ();
} while (PEEKC () == ',');
listline ();
return;
}
lbufp = lbuf;
macroptr->symu.rsmsym.rsmtype.rsmmac.lclcnt = (unsigned char)pMCur->count;
swaphandler = TRUE;
handler = HIRPX;
}
irpxbuild ();
}
/*** macrocall - process macro call
*
* macrocall ();
*
* Entry
* Exit
* Returns
* Calls
*/
#if !defined XENIX286 && !defined FLATMODEL
# pragma check_stack+
#endif
VOID PASCAL CODESIZE
macrocall ()
{
register USHORT cc;
SHORT cbParms;
SYMBOL FARSYM *macro;
static char nullParm[1] = {0};
#ifdef BCBOPT
if (fNotStored)
storelinepb ();
#endif
macro = symptr; /* Ptr to macro entry */
crefnew (REF);
/* Create param area */
optyp = TMACRO;
cbParms = macro->symu.rsmsym.rsmtype.rsmmac.parmcnt;
createMC ((USHORT)(cbParms + macro->symu.rsmsym.rsmtype.rsmmac.lclcnt));
while (--cbParms >= 0) {
/* extract ' ' or ',' terminated parameter */
scanparam (FALSE);
/* check for proper termination parameter termination */
if (((cc = PEEKC ()) != ',') && !ISBLANK (cc) && !ISTERM (cc)) {
errorcSYN ();
NEXTC ();
}
if (ISTERM (cc = skipblanks ()))
break;
if (cc == ',')
SKIPC ();
}
pMCur->pTSCur = pMCur->pTSHead = macro->symu.rsmsym.rsmtype.rsmmac.macrotext; ;
for (cc = pMCur->count;
cc < macro->symu.rsmsym.rsmtype.rsmmac.parmcnt; cc++)
pMCur->rgPV[cc].pActual = nullParm;
pMCur->count = 1;
pMCur->localBase = localbase;
pMCur->iLocal = macro->symu.rsmsym.rsmtype.rsmmac.parmcnt;
localbase += macro->symu.rsmsym.rsmtype.rsmmac.lclcnt;
listline ();
/* Start of macro text */
macrolevel++;
macro->symu.rsmsym.rsmtype.rsmmac.active++;
pMCur->svcondlevel = (char)condlevel;
pMCur->svlastcondon = (char)lastcondon;
pMCur->svelseflag = elseflag;
lineprocess (RMACRO, pMCur);
if (!(--macro->symu.rsmsym.rsmtype.rsmmac.active))
if (macro->symu.rsmsym.rsmtype.rsmmac.delete)
deletemacro (macro);
}
#if !defined XENIX286 && !defined FLATMODEL
# pragma check_stack-
#endif
/*** checkendm - check for ENDM on current line
*
* checkendm ();
*
* Entry
* Exit
* Returns
* Calls
*/
UCHAR PASCAL CODESIZE
checkendm ()
{
char flag;
getatomend ();
if (PEEKC () == '&') { /* skip constructed name */
while (PEEKC () == '&') {
SKIPC ();
getatomend ();
}
*naim.pszName = '\0';
}
if (PEEKC () == ':' || (naim.pszName[0] == '%' && naim.pszName[1] == 0)) {
SKIPC ();
/* Skip over label */
getatomend ();
}
if (flag = (char)fndir ()) {
}
else if (ISBLANK (PEEKC ())) {
/* Check for naim MACRO */
getatomend ();
flag = (char)fndir2 ();
}
if (flag) {
if (opkind & BLKBEG)
blocklevel++;
else if (optyp == TENDM)
blocklevel--;
if (!blocklevel) {
listline ();
return (TRUE);
}
}
return (FALSE);
}
/*** createMC - create parameter descriptor
*/
VOID PASCAL CODESIZE
createMC (
USHORT cParms
){
register MC *pMC;
SHORT cb;
/* Create it */
cb = sizeof(MC) - sizeof(PV) + sizeof(PV) * cParms;
pMCur = pMC = (MC *) nalloc (cb, "creatMC");
memset(pMC, 0, cb);
pMC->flags = optyp;
pMC->cbParms = (USHORT)(linebp - lbufp + 10);
pMC->pParmNames = nalloc(pMC->cbParms, "macrodefine");
pMC->pParmAct = pMC->pParmNames;
*pMC->pParmAct = NULL;
}
/*** deleteMC - delete dummy and parameter lists
*
*
* Entry pMC = parameter descriptor
* Exit descriptor, dummy parameters and local parameters released
* Returns
* Calls
*/
VOID PASCAL CODESIZE
deleteMC (
register MC *pMC
){
if (pMC->flags <= TIRPC)
free(pMC->pParmNames);
free(pMC->pParmAct);
free((char *) pMC);
}
VOID PASCAL CODESIZE
listfree (
TEXTSTR FAR *ptr
){
TEXTSTR FAR *ptrnxt;
while (ptr) {
ptrnxt = ptr->strnext;
tfree ((char FAR *)ptr, (USHORT)ptr->size);
ptr = ptrnxt;
}
}