Annotation of coherent/d/bin/as/asm.c, revision 1.1.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.