Annotation of coherent/d/bin/as/asm.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Segmented assembler.
        !             3:  * Segmented assemblers are much
        !             4:  * more of a pain then non segmented
        !             5:  * ones. Here we try to make them
        !             6:  * easy to use, at the expense of
        !             7:  * driving the implementor absolutely
        !             8:  * crazy.
        !             9:  */
        !            10: #include "asm.h"
        !            11: 
        !            12: main(argc, argv)
        !            13: char *argv[];
        !            14: {
        !            15:        register char *p;
        !            16:        register c, i;
        !            17:        char *sfn;
        !            18:        int nfile, sfx;
        !            19:        static char copen[] = "%s: cannot open.\n";
        !            20: 
        !            21:        nfile = argc-1;
        !            22:        efp = stdout;
        !            23:        for (i=1; i<argc; ++i) {
        !            24:                p = argv[i];
        !            25:                if (*p == '-') {
        !            26:                        argv[i] = NULL;
        !            27:                        --nfile;
        !            28:                        ++p;
        !            29:                        while (c = *p++) {
        !            30:                                switch(c) {
        !            31: 
        !            32:                                case 'g':
        !            33:                                        ++gflag;
        !            34:                                        break;
        !            35: 
        !            36:                                case 'l':
        !            37:                                        ++lflag;
        !            38:                                        efp = stderr;
        !            39:                                        break;
        !            40: 
        !            41:                                case 'o':
        !            42:                                        if (++i >= argc)
        !            43:                                                usage();
        !            44:                                        ofn = argv[i];
        !            45:                                        argv[i] = NULL;
        !            46:                                        --nfile;
        !            47:                                        break;
        !            48:                                case 'x':
        !            49:                                        ++xflag;
        !            50:                                        break;
        !            51: 
        !            52:                                default:
        !            53:                                        usage();
        !            54:                                }
        !            55:                        }
        !            56:                }
        !            57:        }
        !            58:        if (nfile == 0)
        !            59:                usage();
        !            60: #if CPM
        !            61:        ofp = fopen(ofn, "wb");
        !            62: #else
        !            63:        ofp = fopen(ofn, "w");
        !            64: #if !INTEL
        !            65:        if (ofp != NULL)
        !            66:                ofp = freopen(ofn, "r+w", ofp);
        !            67: #endif
        !            68: #endif
        !            69:        if (ofp == NULL) {
        !            70:                fprintf(stderr, "%s: cannot create.\n", ofn);
        !            71:                exit(1);
        !            72:        }
        !            73: #if !RSX && !CPM
        !            74:        setbuf(ofp, NULL);
        !            75: #endif
        !            76:        syminit();
        !            77:        locinit();
        !            78:        for (pass = 0; pass < 3; ++pass) {
        !            79:                if (pass==1 && gflag)
        !            80:                        symglob();
        !            81:                if (pass == 2) {
        !            82:                        locadjust();
        !            83:                        outinit();
        !            84:                }
        !            85:                sfx  = 1;
        !            86:                page = 0;
        !            87:                lop  = NLPP;
        !            88:                if (sfp != NULL) {
        !            89:                        fseek(sfp, (long)0, 0);
        !            90:                        line = 0;
        !            91:                }
        !            92:                loczero();
        !            93:                fuzz = 0;
        !            94: #if MINIT
        !            95:                minit();
        !            96: #endif
        !            97:                dot->s_kind = S_USER;
        !            98:                dot->s_type = E_DIR;
        !            99:                dot->s_addr = defloc->l_offset;
        !           100:                dot->s_base.s_lp = defloc;
        !           101:                setinbss();
        !           102:                if (pass != 0) {
        !           103:                        for (i=0; i<10; ++i) {
        !           104:                                tsymp[i].tp_bp = NULL;
        !           105:                                tsymp[i].tp_fp = tsymp[i].tp_lfp;
        !           106:                        }
        !           107:                }
        !           108:                for (;;) {
        !           109:                        if (sfp == NULL) {
        !           110:                                sfn = NULL;
        !           111:                                while (sfx<argc && (sfn=argv[sfx++])==NULL)
        !           112:                                        ;
        !           113:                                if (sfn == NULL)
        !           114:                                        break;
        !           115:                                if ((sfp = fopen(sfn, "r")) == NULL) {
        !           116:                                        fprintf(stderr, copen, sfn);
        !           117:                                        exit(1);
        !           118:                                }
        !           119:                                if (nfile != 1)
        !           120:                                        ifn = sfn;
        !           121:                                line = 0;
        !           122:                                lop  = NLPP;
        !           123:                        }
        !           124:                        if (getline() == 0) {
        !           125:                                if (nfile == 1)
        !           126:                                        break;
        !           127:                                fclose(sfp);
        !           128:                                sfp = NULL;
        !           129:                                continue;
        !           130:                        }
        !           131:                        ++line;
        !           132:                        cp = cb;
        !           133:                        ep = eb;
        !           134:                        ip = ib;
        !           135:                        if (setjmp(env) == 0)
        !           136:                                asm();
        !           137:                        if (pass == 2)
        !           138:                                list();
        !           139:                }
        !           140:                newloc(NULL);
        !           141:        }
        !           142:        outfinish();
        !           143:        if (nerr != 0) {
        !           144:                if (lflag)
        !           145:                        fprintf(efp, "%d error%s detected\n",
        !           146:                                nerr, ((nerr != 1) ? "s" : ""));
        !           147:                unlink(ofn);
        !           148:                exit(1);
        !           149:        }
        !           150: #if    0
        !           151: #if !RSX && !CPM
        !           152:        chmod(ofn, 0755);
        !           153: #endif
        !           154: #endif
        !           155:        exit(0);
        !           156: }
        !           157: 
        !           158: asm()
        !           159: {
        !           160:        register struct sym *sp;
        !           161:        register struct tsym *tp;
        !           162:        register c;
        !           163:        address cs;
        !           164:        struct tsymp *tsp;
        !           165:        struct expr e1;
        !           166:        char id[NCPLN];
        !           167:        char *p;
        !           168:        int d;
        !           169: 
        !           170:        laddr = dot->s_addr;
        !           171:        lmode = SLIST;
        !           172: loop:
        !           173:        while ((c=getnb()) == ';')
        !           174:                ;
        !           175:        if (c==0 || c=='/')
        !           176:                return;
        !           177:        if (ctype[c] == DIGIT) {
        !           178:                if (get() != ':')
        !           179:                        qerr("invalid local symbol");
        !           180:                tsp = &tsymp[c-'0'];
        !           181:                if (pass == 0) {
        !           182:                        tp = (struct tsym *) new(sizeof(struct tsym));
        !           183:                        tp->t_fp = NULL;
        !           184:                        tp->t_lp = dot->s_base.s_lp;
        !           185:                        tp->t_addr = dot->s_addr;
        !           186:                        if (tsp->tp_lfp == NULL)
        !           187:                                tsp->tp_lfp = tp; else
        !           188:                                tsp->tp_llp->t_fp = tp;
        !           189:                        tsp->tp_llp = tp;
        !           190:                } else {
        !           191:                        tp = tsp->tp_fp;
        !           192:                        if (pass == 1) {
        !           193:                                fuzz = tp->t_addr - dot->s_addr;
        !           194:                                tp->t_lp = dot->s_base.s_lp;
        !           195:                                tp->t_addr = dot->s_addr;
        !           196:                        } else
        !           197:                                phase(tp->t_lp, tp->t_addr);
        !           198:                }
        !           199:                tsp->tp_bp = tp;
        !           200:                tsp->tp_fp = tp->t_fp;
        !           201:                goto loop;
        !           202:        }
        !           203:        if (ctype[c] != LETTER) 
        !           204:                qerr("invalid identifier");
        !           205:        getid(id, c);
        !           206:        if ((c=getnb()) == ':') {
        !           207:                sp = lookup(id, 1);
        !           208:                if (sp == dot)
        !           209:                        err('.', "'.' declared as label");
        !           210:                if (pass == 0)
        !           211:                        if (sp->s_type!=S_NEW && (sp->s_flag&S_ASG)==0)
        !           212:                                sp->s_flag |= S_MDF;
        !           213:                if (pass != 2) {
        !           214:                        fuzz = sp->s_addr - dot->s_addr;
        !           215:                        sp->s_kind = S_USER;
        !           216:                        sp->s_type = E_DIR;
        !           217:                        sp->s_base.s_lp = dot->s_base.s_lp;
        !           218:                        sp->s_addr = dot->s_addr;
        !           219:                } else {
        !           220:                        if ((sp->s_flag&S_MDF) != 0)
        !           221:                                err('m', "multiply defined symbol");
        !           222:                        phase(sp->s_base.s_lp, sp->s_addr);
        !           223:                }
        !           224:                lmode = ALIST;
        !           225:                goto loop;
        !           226:        }
        !           227:        if (c == '=') {
        !           228:                expr(&e1, 0);
        !           229:                if ((sp=lookup(id, 1)) == dot) {
        !           230: #if INTEL
        !           231:                        dot->s_addr = e1.e_addr;
        !           232: #else
        !           233:                        if (okdot(&e1)) {
        !           234:                                if (inbss == 0)
        !           235:                                        zblock(e1.e_addr-dot->s_addr);
        !           236:                                else
        !           237:                                        dot->s_addr = e1.e_addr;
        !           238:                        }
        !           239: #endif
        !           240:                } else {
        !           241:                        if (sp->s_type!=S_NEW && (sp->s_flag&S_ASG)==0)
        !           242:                                err('m', "multiply defined symbol");
        !           243:                        sp->s_kind = S_USER;
        !           244:                        sp->s_type = e1.e_type;
        !           245:                        if (e1.e_type == E_ASEG)
        !           246:                                sp->s_base.s_segn = e1.e_base.e_segn;
        !           247:                        else if (e1.e_type == E_DIR)
        !           248:                                sp->s_base.s_lp = e1.e_base.e_lp;
        !           249:                        else if (e1.e_type==E_SYM || e1.e_type==E_SEG)
        !           250:                                sp->s_base.s_sp = e1.e_base.e_sp;
        !           251:                        sp->s_addr = e1.e_addr;
        !           252:                        sp->s_flag |= S_ASG;
        !           253:                }
        !           254:                laddr = e1.e_addr;
        !           255:                lmode = ALIST;
        !           256:                goto loop;
        !           257:        }
        !           258:        unget(c);
        !           259:        lmode = CLIST;
        !           260:        if ((sp=lookup(id, 0)) == NULL) {
        !           261:                uerr(id);
        !           262:                return;
        !           263:        }
        !           264:        switch (sp->s_kind) {
        !           265: 
        !           266:        case S_BYTE:
        !           267:        case S_WORD:
        !           268:                do {
        !           269:                        expr(&e1, 0);
        !           270:                        if (sp->s_kind == S_BYTE)
        !           271:                                outrb(&e1, 0); else
        !           272:                                outrw(&e1, 0);
        !           273:                } while ((c = getnb()) == ',');
        !           274:                unget(c);
        !           275:                if (sp->s_kind == S_BYTE)
        !           276:                        lmode = BLIST; else
        !           277:                        lmode = WLIST;
        !           278:                break;
        !           279: 
        !           280:        case S_ASCII:
        !           281:                if ((d = getnb()) == '\0')
        !           282:                        qerr("end of line in string");
        !           283:                while ((c = getmap(d)) >= 0)
        !           284:                        outab(c);
        !           285:                lmode = BLIST;
        !           286:                break;
        !           287: 
        !           288:        case S_BLK:
        !           289:                cs = absexpr()*sp->s_addr;
        !           290:                if (inbss == 0)
        !           291:                        zblock(cs);  else
        !           292:                        dot->s_addr += cs;
        !           293:                lmode = ALIST;
        !           294:                break;
        !           295: 
        !           296:        case S_TITLE:
        !           297:                p = tb;
        !           298:                if (c = getnb()) {
        !           299:                        do {
        !           300:                                if (p < &tb[NTIT-1])
        !           301:                                        *p++ = c;
        !           302:                        } while (c = get());
        !           303:                }
        !           304:                *p = 0;
        !           305:                unget(c);
        !           306: 
        !           307:        case S_PAGE:
        !           308:                lop = NLPP;
        !           309:                lmode = NLIST;
        !           310:                break;
        !           311: 
        !           312:        case S_GLOBL:
        !           313:                do {
        !           314:                        getid(id, -1);
        !           315:                        lookup(id, 1)->s_flag |= S_GBL;
        !           316:                } while ((c = getnb()) == ',');
        !           317:                unget(c);
        !           318:                lmode = SLIST;
        !           319:                break;
        !           320: 
        !           321:        case S_COMM:
        !           322:                getid(id, -1);
        !           323:                if (getnb() != ',')
        !           324:                        qerr("expected comma");
        !           325:                cs = locrup(absexpr());
        !           326:                sp = lookup(id, 1);
        !           327:                if (sp->s_kind == S_NEW) {
        !           328:                        sp->s_flag |= S_GBL;
        !           329:                        if (cs > sp->s_addr)
        !           330:                                sp->s_addr = cs;
        !           331:                }
        !           332:                lmode = SLIST;
        !           333:                break;
        !           334: 
        !           335:        case S_LOC:
        !           336:                newloc((struct loc *) sp->s_addr);
        !           337:                lmode = SLIST;
        !           338:                break;
        !           339: 
        !           340:        default:
        !           341:                machine(sp);
        !           342:        }
        !           343:        goto loop;
        !           344: }
        !           345: 
        !           346: okdot(esp)
        !           347: register struct expr *esp;
        !           348: {
        !           349:        if (esp->e_type!=E_DIR || esp->e_base.e_lp!=dot->s_base.s_lp) {
        !           350:                rerr("not a direct address in this segment");
        !           351:                return (0);
        !           352:        }
        !           353:        if (esp->e_addr < dot->s_addr) {
        !           354:                aerr("cannot move . back");
        !           355:                return (0);
        !           356:        }
        !           357:        return (1);
        !           358: }
        !           359: 
        !           360: zblock(n)
        !           361: address n;
        !           362: {
        !           363:        while (n--)
        !           364:                outab(0);
        !           365: }
        !           366: 
        !           367: usage()
        !           368: {
        !           369:        fprintf(stderr, "Usage: as [-glx] [-o file] file [file ...]\n");
        !           370:        exit(1);
        !           371: }
        !           372: 
        !           373: phase(lp, a)
        !           374: struct loc *lp;
        !           375: address a;
        !           376: {
        !           377:        if (dot->s_base.s_lp!=lp || dot->s_addr!=a)
        !           378:                err('p', "phase error");
        !           379: }
        !           380: 
        !           381: newloc(nlp)
        !           382: register struct loc *nlp;
        !           383: {
        !           384:        register struct loc *olp;
        !           385: 
        !           386:        if ((olp = dot->s_base.s_lp) != NULL) {
        !           387:                olp->l_fuzz = fuzz;
        !           388:                olp->l_break = dot->s_addr - olp->l_offset;
        !           389:        }
        !           390:        if (nlp != NULL) {
        !           391:                dot->s_base.s_lp = nlp;
        !           392:                dot->s_addr = nlp->l_break + nlp->l_offset;
        !           393:                fuzz = nlp->l_fuzz;
        !           394:        }
        !           395:        setinbss();
        !           396: #if !INTEL
        !           397:        if (pass == 2)
        !           398:                outchk(HUGE, HUGE);
        !           399: #endif
        !           400: }
        !           401: 
        !           402: loczero()
        !           403: {
        !           404:        register struct loc *lp;
        !           405:        register i;
        !           406: 
        !           407:        for (i=0; i<nloc; ++i) {
        !           408:                lp = loc[i];
        !           409:                while (lp != NULL) {
        !           410:                        lp->l_fuzz  = 0;
        !           411:                        lp->l_break = 0;
        !           412:                        lp = lp->l_lp;
        !           413:                }
        !           414:        }
        !           415: }
        !           416: 
        !           417: locadjust()
        !           418: {
        !           419:        register struct sym  *sp;
        !           420:        register struct loc  *lp;
        !           421:        register struct tsym *tp;
        !           422:        address offset;
        !           423:        int i;
        !           424: 
        !           425: #if !SEG
        !           426:        offset = 0;
        !           427: #endif
        !           428:        for (i=0; i<nloc; ++i) {
        !           429: #if  SEG
        !           430:                offset = 0;
        !           431: #endif
        !           432:                lp = loc[i];
        !           433:                while (lp != NULL) {
        !           434:                        lp->l_offset = offset;
        !           435:                        offset += locrup(lp->l_break);
        !           436:                        lp = lp->l_lp;
        !           437:                }
        !           438:        }
        !           439:        for (i=0; i<10; ++i) {
        !           440:                tp = tsymp[i].tp_lfp;
        !           441:                while (tp != NULL) {
        !           442:                        if ((lp = tp->t_lp) != NULL)
        !           443:                                tp->t_addr += lp->l_offset;
        !           444:                        tp = tp->t_fp;
        !           445:                }
        !           446:        }
        !           447:        for (i=0; i<NHASH; ++i) {
        !           448:                sp = symhash[i];
        !           449:                while (sp != NULL) {
        !           450:                        if (sp->s_kind == S_USER &&
        !           451:                            sp->s_type == E_DIR  &&
        !           452:                           (lp=sp->s_base.s_lp) != NULL)
        !           453:                                sp->s_addr += lp->l_offset;
        !           454:                        sp = sp->s_sp;
        !           455:                }
        !           456:        }
        !           457: }
        !           458: 
        !           459: setinbss()
        !           460: {
        !           461:        register struct loc *lp;
        !           462: 
        !           463:        inbss = 0;
        !           464:        lp = dot->s_base.s_lp;
        !           465: #if SEG
        !           466:        if (lp->l_seg == BSS)
        !           467: #else
        !           468:        if (lp->l_seg==L_BSSI || lp->l_seg==L_BSSD)
        !           469: #endif
        !           470:                ++inbss;
        !           471: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.