/* asmdir.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 #include #include "asm86.h" #include "asmfcn.h" #include #include #include #ifndef XENIX286 #include #include #endif #include "asmctype.h" #include "asmindex.h" #include "asmmsg.h" extern PFPOSTRUCT pFpoHead; extern PFPOSTRUCT pFpoTail; extern unsigned long numFpoRecords; SHORT CODESIZE fetLang(void); int PASCAL CODESIZE trypathname PARMS((char *)); int PASCAL CODESIZE openincfile PARMS(( void )); VOID PASCAL CODESIZE creatPubName (void); extern char *siznm[]; /*** setsymbol - set attribute in symbol * * setsymbol (bit); * * Entry * Exit * Returns * Calls */ VOID PASCAL CODESIZE setsymbol ( UCHAR bit ) { /* Scan symbol name */ if (getatom ()) { if (!symsrch ()) errorn (E_SND); symptr->attr |= bit; } } /*** publicitem - scan symbol and make PUBLIC * * publicitem (); * * Entry naim = symbol name * Exit Global attribute set in symbol entry * Returns none * Calls error, scanatom, symsearch */ VOID PASCAL CODESIZE publicitem() { static char newAttr; if (getatom ()) { newAttr = NULL; if (fetLang() == CLANG) newAttr = M_CDECL; if (!symsrch ()) { /* define forward refernced name, so global attribute * is available on the end of pass 1 */ symcreate ( (UCHAR)(M_GLOBAL | newAttr), (UCHAR)PROC); } else { symptr->attr |= newAttr; /* public is legal for an alias if target ok */ if (symptr->symkind == EQU && symptr->symu.equ.equtyp == ALIAS) if (! (symptr = chasealias (symptr))) { errorc(E_TUL); return; } if (pass2) { /* catch forward reference symbol errors */ if (! (symptr->attr & M_GLOBAL)) errorn (E_IFR); else if ((symptr->attr&~M_CDECL) == M_GLOBAL || !(symptr->attr & M_DEFINED)) errorn (E_SND); } switch (symptr->symkind) { case PROC: case DVAR: case CLABEL: if (M_XTERN & symptr->attr) errorc (E_SAE); break; case EQU: if (symptr->symu.equ.equtyp != EXPR) errorc (E_TUL); break; default: errorc (E_TUL); } } creatPubName(); } } VOID PASCAL CODESIZE creatPubName () { symptr->attr |= M_GLOBAL; if (caseflag == CASEX && symptr->lcnamp == NULL) symptr->lcnamp = #ifdef M8086 creatlname (naim.pszLowerCase); #else createname (naim.pszLowerCase); #endif } /*** xcrefitem - scan symbol and xcref it * * xcrefitem (); * * Entry * Exit * Returns * Calls */ VOID PASCAL CODESIZE xcrefitem () { if (pass2 && !loption) { setsymbol (M_NOCREF); creftype = CREFEND; } else getatom (); } /*** externflag - * * routine (); * * Entry * Exit * Returns * Calls */ VOID PASCAL CODESIZE externflag ( register UCHAR kind, register UCHAR new ) { switchname (); /* Make name be extern name */ if (!new) { /* Create symbol */ symcreate (M_XTERN | M_DEFINED, (UCHAR)((kind == CLABEL)? DVAR: kind)); symptr->symkind = kind; if (caseflag == CASEX) symptr->lcnamp = #ifdef M8086 creatlname (naim.pszLowerCase); #else createname (naim.pszLowerCase); #endif /* M8086 */ symptr->symtype = varsize; symptr->length = 1; if (kind == EQU) /* expr type EQU is constant */ symptr->symu.equ.equtyp = EXPR; else symptr->symsegptr = pcsegment; if (pass2) emitextern (symptr); } checkRes(); crefdef (); if (! (M_XTERN & symptr->attr)) errorc (E_ALD); else { if (kind != symptr->symkind || symptr->symtype != varsize || (symptr->length != 1 && kind != EQU) && (symptr->symsegptr != pcsegment && !(fSimpleSeg && varsize == CSFAR))) errorn (E_SDK); else { symptr->attr |= M_XTERN | M_BACKREF; if (fSimpleSeg && varsize == CSFAR) { symptr->symsegptr = NULL; } else if (varsize == CSNEAR || (varsize == CSFAR && pcsegment)) symptr->symu.clabel.csassume = regsegment[CSSEG]; } } } /*** externitem - * * externitem (); * * Entry * Exit * Returns * Calls */ VOID PASCAL CODESIZE externitem () { register char new; char newAttr; /* Get name of external */ if (getatom ()) { newAttr = NULL; if (fetLang() == CLANG) newAttr = M_CDECL; new = symFetNoXref (); switchname (); /* Save name of external */ if (NEXTC () != ':') errorc (E_SYN); else { /* Scan name of extern type */ getatom (); if (tokenIS("abs")) { equsel = EXPR; varsize = 0; externflag (EQU, new); } else if (!fnsize ()) errorc (E_UST); else { if (varsize >= CSFAR) { /* NEAR | FAR */ externflag (CLABEL, new); } else /* data reference */ externflag (DVAR, new); } symptr->attr |= newAttr; } } } /*** segcreate - create and initialize segment * * segcreate (makeseg); * * Entry makeseg = TRUE if segement is to be make * Exit * Returns * Calls */ VOID PASCAL CODESIZE segcreate ( register UCHAR makeseg ) { if (pass2) /* Segment must be defined */ errorn (E_PS1); if (makeseg) symcreate (0, SEGMENT); else symptr->symkind = SEGMENT; /* Initialize segment data */ symptr->symu.segmnt.align = -1; symptr->symu.segmnt.use32 = -1; symptr->symu.segmnt.combine = 7; } /*** addglist - add segment to group list * * addglist (); * * Entry * Exit * Returns * Calls */ VOID PASCAL CODESIZE addglist () { register SYMBOL FARSYM *p, FARSYM *pSY; p = symptr; if (pass2) if (!(M_DEFINED & p->attr)) errorn (E_PS1); /* Can get segment in 2 group lists unless check * symptr->grouptr == curgroup */ if (p->symu.segmnt.grouptr) { if (p->symu.segmnt.grouptr != curgroup) /* Trying to put in 2 groups */ errorc (E_SPC); return; } p->symu.segmnt.grouptr = curgroup; pSY = curgroup->symu.grupe.segptr; if (!pSY) curgroup->symu.grupe.segptr = p; else { /* scan the list of segments on the group */ do { if (pSY == p) /* already on list */ return; } while (pSY->symu.segmnt.nxtseg && (pSY = pSY->symu.segmnt.nxtseg)); /* Link into list */ pSY->symu.segmnt.nxtseg = p; } } /*** groupitem - * * routine (); * * Entry * Exit * Returns * Calls */ VOID PASCAL CODESIZE groupitem () { if (!getatom ()) error (E_EXP,"segment name"); else if (!fnoper ()) { /* Have a segment name */ if (!symFet()) /* Forward segment, make it */ segcreate (TRUE); /* If not segment, could be class so make undef */ if (symptr->symkind != SEGMENT) /* If a class, consider undef instead of wrong kind */ errorn ((USHORT)((symptr->symkind == CLASS) && !pass2 ? E_IFR : E_SDK)); else if (symptr->attr & M_DEFINED || !pass2) { if (curgroup) addglist (); } else errorn (E_PS1); } else { /* Have error or SEG */ if (opertype != OPSEG) /* Symbol can't be reserved */ errorn (E_RES); else { /* Have SEG |