Annotation of quakeworld/gas2masm/gas2masm.c, revision 1.1.1.1

1.1       root        1: /*
                      2: Copyright (C) 1996-1997 Id Software, Inc.
                      3: 
                      4: This program is free software; you can redistribute it and/or
                      5: modify it under the terms of the GNU General Public License
                      6: as published by the Free Software Foundation; either version 2
                      7: of the License, or (at your option) any later version.
                      8: 
                      9: This program is distributed in the hope that it will be useful,
                     10: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
                     12: 
                     13: See the GNU General Public License for more details.
                     14: 
                     15: You should have received a copy of the GNU General Public License
                     16: along with this program; if not, write to the Free Software
                     17: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
                     18: 
                     19: */
                     20: //
                     21: // gas to MASM source code converter
                     22: //
                     23: 
                     24: #include <stdio.h>
                     25: #include <stdlib.h>
                     26: #include <string.h>
                     27: 
                     28: #define MAX_TOKENS                     100
                     29: #define MAX_TOKEN_LENGTH       1024
                     30: #define LF                                     0x0A
                     31: 
                     32: typedef enum {NOT_WHITESPACE, WHITESPACE, TOKEN_AVAILABLE, LINE_DONE, FILE_DONE, PARSED_OKAY} tokenstat;
                     33: typedef enum {NOSEG, DATASEG, TEXTSEG} segtype;
                     34: 
                     35: int            tokennum;
                     36: int            inline, outline;
                     37: 
                     38: char   *token;
                     39: char   tokens[MAX_TOKENS][MAX_TOKEN_LENGTH+1];
                     40: 
                     41: segtype        currentseg = NOSEG;
                     42: 
                     43: typedef struct {
                     44:        char    *text;
                     45:        char    *emit;
                     46:        int             numtokens;
                     47:        void    (*parsefunc) (void);
                     48: } parsefield;
                     49: 
                     50: 
                     51: void errorexit (void);
                     52: 
                     53: 
                     54: //==============================================
                     55: 
                     56: typedef struct {
                     57:        char    *text;
                     58:        char    *emit;
                     59:        int             len;
                     60: } regdesc;
                     61: 
                     62: regdesc        reglist[] = {
                     63:        {"%eax", "eax", 4},
                     64:        {"%ebx", "ebx", 4},
                     65:        {"%ecx", "ecx", 4},
                     66:        {"%edx", "edx", 4},
                     67:        {"%esi", "esi", 4},
                     68:        {"%edi", "edi", 4},
                     69:        {"%ebp", "ebp", 4},
                     70:        {"%esp", "esp", 4},
                     71:        {"%ax", "ax", 3},
                     72:        {"%bx", "bx", 3},
                     73:        {"%cx", "cx", 3},
                     74:        {"%dx", "dx", 3},
                     75:        {"%si", "si", 3},
                     76:        {"%di", "di", 3},
                     77:        {"%bp", "bp", 3},
                     78:        {"%sp", "sp", 3},
                     79:        {"%al", "al", 3},
                     80:        {"%bl", "bl", 3},
                     81:        {"%cl", "cl", 3},
                     82:        {"%dl", "dl", 3},
                     83:        {"%ah", "ah", 3},
                     84:        {"%bh", "bh", 3},
                     85:        {"%ch", "ch", 3},
                     86:        {"%dh", "dh", 3},
                     87:        {"%st(0)", "st(0)", 6},
                     88:        {"%st(1)", "st(1)", 6},
                     89:        {"%st(2)", "st(2)", 6},
                     90:        {"%st(3)", "st(3)", 6},
                     91:        {"%st(4)", "st(4)", 6},
                     92:        {"%st(5)", "st(5)", 6},
                     93:        {"%st(6)", "st(6)", 6},
                     94:        {"%st(7)", "st(7)", 6},
                     95: };
                     96: 
                     97: int    numregs = sizeof (reglist) / sizeof (reglist[0]);
                     98: 
                     99: //==============================================
                    100: 
                    101: 
                    102: void emitanoperand (int tnum, char *type, int notdata)
                    103: {
                    104:        int             i, index, something_outside_parens, regfound;
                    105:        int             parencount;
                    106:        char    *pt;
                    107:        char    temp[MAX_TOKEN_LENGTH+1];
                    108: 
                    109:        pt = tokens[tnum];
                    110: 
                    111:        if (pt[0] == '%')
                    112:        {
                    113:        // register
                    114:                for (i=0 ; i<numregs ; i++)
                    115:                {
                    116:                        if (!strcmpi (pt, reglist[i].text))
                    117:                        {
                    118:                                printf ("%s", reglist[i].emit);
                    119:                                return;
                    120:                        }
                    121:                }
                    122: 
                    123:                fprintf (stderr, "Error: bad register %s\n", pt);
                    124:                errorexit ();
                    125:        }
                    126:        else if (pt[0] == '$')
                    127:        {
                    128:        // constant
                    129:                if (pt[1] == '(')
                    130:                {
                    131:                        if ((pt[2] > '9') || (pt[2] < '0'))
                    132:                        {
                    133:                                i = 2;
                    134:                                printf ("offset ");
                    135: 
                    136:                                parencount = 1;
                    137: 
                    138:                                while ((pt[i] != ')') || (parencount > 1))
                    139:                                {
                    140:                                        if (!pt[i])
                    141:                                        {
                    142:                                                fprintf (stderr, "mismatched parens");
                    143:                                                errorexit ();
                    144:                                        }
                    145: 
                    146:                                        if (pt[i] == ')')
                    147:                                                parencount--;
                    148:                                        else if (pt[i] == '(')
                    149:                                                parencount++;
                    150: 
                    151:                                        printf ("%c", pt[i]);
                    152:                                        i++;
                    153:                                }
                    154:                        }
                    155:                        else
                    156:                        {
                    157:                                pt++;
                    158: 
                    159:                                parencount = 1;
                    160: 
                    161:                                for (i=1 ; (pt[i] != ')') || (parencount > 1) ; i++)
                    162:                                {
                    163:                                        if (!pt[i])
                    164:                                        {
                    165:                                                fprintf (stderr, "mismatched parens");
                    166:                                                errorexit ();
                    167:                                        }
                    168: 
                    169:                                        if (pt[i] == ')')
                    170:                                                parencount--;
                    171:                                        else if (pt[i] == '(')
                    172:                                                parencount++;
                    173:                                }
                    174: 
                    175:                                pt[i] = 0;
                    176: 
                    177:                                if ((pt[1] == '0') && ((pt[2] == 'x') || (pt[2] == 'X')))
                    178:                                {
                    179:                                        printf ("0%sh", &pt[3]);
                    180:                                }
                    181:                                else
                    182:                                {
                    183:                                        printf ("%s", &pt[1]);
                    184:                                }
                    185:                        }
                    186:                }
                    187:                else if ((pt[1] == '0') && ((pt[2] == 'x') || (pt[2] == 'X')))
                    188:                {
                    189:                        printf ("0%sh", &pt[3]);
                    190:                }
                    191:                else if ((pt[1] >= '0') && (pt[1] <= '9'))
                    192:                {
                    193:                        printf ("%s", &pt[1]);
                    194:                }
                    195:                else
                    196:                {
                    197:                        printf ("offset %s", &pt[1]);
                    198:                }
                    199:        }
                    200:        else if (!notdata && ((pt[0] >= '0') && (pt[0] <= '9')))
                    201:        {
                    202:                pt--;
                    203: 
                    204:                if ((pt[1] == '0') && ((pt[2] == 'x') || (pt[2] == 'X')))
                    205:                {
                    206:                        printf ("0%sh", &pt[3]);
                    207:                }
                    208:                else
                    209:                {
                    210:                        printf ("%s", &pt[1]);
                    211:                }
                    212:        }
                    213:        else
                    214:        {
                    215:        // must be a memory location
                    216:                strcpy (temp, type);
                    217:                index = strlen (temp);
                    218: 
                    219:                if (notdata)
                    220:                        temp[index++] = '[';
                    221: 
                    222:                something_outside_parens = 0;
                    223: 
                    224:                while (*pt)
                    225:                {
                    226:                        if (index > (MAX_TOKEN_LENGTH - 10))
                    227:                        {
                    228:                                fprintf (stderr, "Error: operand too long %s\n",
                    229:                                                 tokens[tnum]);
                    230:                                errorexit ();
                    231:                        }
                    232: 
                    233:                        if (*pt != ')')
                    234:                        {
                    235:                                if (*pt == '(')
                    236:                                {
                    237:                                        if (something_outside_parens)
                    238:                                                temp[index++] = '+';
                    239:                                }
                    240:                                else if (*pt == '%')
                    241:                                {
                    242:                                        regfound = 0;
                    243: 
                    244:                                        for (i=0 ; i<numregs ; i++)
                    245:                                        {
                    246:                                                if (!strnicmp (pt, reglist[i].text,
                    247:                                                        reglist[i].len))
                    248:                                                {
                    249:                                                        strcpy (&temp[index], reglist[i].emit);
                    250:                                                        index += strlen (reglist[i].emit);
                    251:                                                        pt += strlen (reglist[i].text) - 1;
                    252:                                                        regfound = 1;
                    253:                                                        break;
                    254:                                                }
                    255:                                        }
                    256: 
                    257:                                        if (!regfound)
                    258:                                        {
                    259:                                                fprintf (stderr, "Error: bad register %s\n", pt);
                    260:                                                errorexit ();
                    261:                                        }
                    262:                                }
                    263:                                else if (*pt == ',')
                    264:                                {
                    265:                                        pt++;
                    266: 
                    267:                                        if ((*pt >= '1') && (*pt <= '8'))
                    268:                                        {
                    269:                                                temp[index++] = '*';
                    270:                                                temp[index++] = *pt;
                    271:                                        }
                    272:                                        else if (*pt != ')')
                    273:                                        {
                    274:                                                if (temp[index-1] != '+')
                    275:                                                        temp[index++] = '+';
                    276:                                        }
                    277:                                }
                    278:                                else
                    279:                                {
                    280:                                        something_outside_parens = 1;
                    281: 
                    282:                                        // handle hexadecimal constants in addresses
                    283:                                        if ((*pt == '0') &&
                    284:                                                ((*(pt+1) == 'x') || (*(pt+1) == 'X')))
                    285:                                        {
                    286:                                                pt += 2;
                    287: 
                    288:                                                do
                    289:                                                {
                    290:                                                        temp[index++] = *pt++;
                    291:                                                } while (((*pt >= '0') && (*pt <= '9'))     ||
                    292:                                                                 ((*pt >= 'a') && (*pt <= 'f')) ||
                    293:                                                                 ((*pt >= 'A') && (*pt <= 'F')));
                    294: 
                    295:                                                pt--;
                    296:                                                temp[index++] = 'h';
                    297:                                        }
                    298:                                        else
                    299:                                        {
                    300:                                                temp[index++] = *pt;
                    301:                                        }
                    302:                                }
                    303:                        }
                    304: 
                    305:                        pt++;
                    306:                }
                    307: 
                    308:                if (notdata)
                    309:                        temp[index++] = ']';
                    310: 
                    311:                temp[index] = 0;
                    312:                printf ("%s", temp);
                    313:        }
                    314: }
                    315: 
                    316: 
                    317: void datasegstart (void)
                    318: {
                    319:        if (currentseg == DATASEG)
                    320:                return;
                    321: 
                    322:        if (currentseg == TEXTSEG)
                    323:                printf ("_TEXT ENDS\n");
                    324: 
                    325:        printf ("_DATA SEGMENT");
                    326: 
                    327:        currentseg = DATASEG;
                    328: }
                    329: 
                    330: 
                    331: void textsegstart (void)
                    332: {
                    333:        if (currentseg == TEXTSEG)
                    334:                return;
                    335: 
                    336:        if (currentseg == DATASEG)
                    337:                printf ("_DATA ENDS\n");
                    338: 
                    339:        printf ("_TEXT SEGMENT");
                    340: 
                    341:        currentseg = TEXTSEG;
                    342: }
                    343: 
                    344: 
                    345: void emitdata (void)
                    346: {
                    347:        int             i;
                    348: 
                    349:        for (i=1 ; i<(tokennum-1) ; i++)
                    350:                printf (" %s,", tokens[i]);
                    351: 
                    352:        printf (" %s", tokens[tokennum-1]);
                    353: }
                    354: 
                    355: 
                    356: void emitonedata (void)
                    357: {
                    358: 
                    359:        printf (" %s", tokens[1]);
                    360: }
                    361: 
                    362: 
                    363: void emitonecalldata (void)
                    364: {
                    365:        int     i, isaddr, len;
                    366: 
                    367:        if (tokens[1][0] == '*')
                    368:        {
                    369:                printf (" dword ptr[%s]", &tokens[1][1]);
                    370:        }
                    371:        else
                    372:        {
                    373:                isaddr = 0;
                    374:                len = strlen(tokens[1]);
                    375: 
                    376:                for (i=0 ; i<len ; i++)
                    377:                {
                    378:                        if (tokens[1][i] == '(')
                    379:                        {
                    380:                                isaddr = 1;
                    381:                                break;
                    382:                        }
                    383:                }
                    384: 
                    385:                if (!isaddr)
                    386:                {
                    387:                        printf (" near ptr %s", tokens[1]);
                    388:                }
                    389:                else
                    390:                {
                    391:                        emitanoperand (1, " dword ptr", 1);
                    392:                }
                    393:        }
                    394: }
                    395: 
                    396: 
                    397: void emitonejumpdata (void)
                    398: {
                    399:        int     i, isaddr, len;
                    400: 
                    401:        if (tokens[1][0] == '*')
                    402:        {
                    403:                printf (" dword ptr[%s]", &tokens[1][1]);
                    404:        }
                    405:        else
                    406:        {
                    407:                isaddr = 0;
                    408:                len = strlen(tokens[1]);
                    409: 
                    410:                for (i=0 ; i<len ; i++)
                    411:                {
                    412:                        if (tokens[1][i] == '(')
                    413:                        {
                    414:                                isaddr = 1;
                    415:                                break;
                    416:                        }
                    417:                }
                    418: 
                    419:                if (!isaddr)
                    420:                {
                    421:                        printf (" %s", tokens[1]);
                    422:                }
                    423:                else
                    424:                {
                    425:                        emitanoperand (1, " dword ptr", 1);
                    426:                }
                    427:        }
                    428: }
                    429: 
                    430: 
                    431: void emitexterndef (void)
                    432: {
                    433: 
                    434:        printf (" %s:dword", tokens[1]);
                    435: }
                    436: 
                    437: 
                    438: void nooperands (void)
                    439: {
                    440: 
                    441: }
                    442: 
                    443: 
                    444: void emitoneoperandl (void)
                    445: {
                    446: 
                    447:        printf (" ");
                    448:        emitanoperand (1, "ds:dword ptr", 1);
                    449: }
                    450: 
                    451: 
                    452: void emitoneoperandb (void)
                    453: {
                    454: 
                    455:        printf (" ");
                    456:        emitanoperand (1, "ds:byte ptr", 1);
                    457: }
                    458: 
                    459: 
                    460: void emitoneoperandw (void)
                    461: {
                    462: 
                    463:        printf (" ");
                    464:        emitanoperand (1, "ds:word ptr", 1);
                    465: }
                    466: 
                    467: 
                    468: void emittwooperandsl (void)
                    469: {
                    470: 
                    471:        printf (" ");
                    472:        emitanoperand (2, "ds:dword ptr", 1);
                    473:        printf (",");
                    474:        emitanoperand (1, "ds:dword ptr", 1);
                    475: }
                    476: 
                    477: 
                    478: void emittwooperandsb (void)
                    479: {
                    480: 
                    481:        printf (" ");
                    482:        emitanoperand (2, "ds:byte ptr", 1);
                    483:        printf (",");
                    484:        emitanoperand (1, "ds:byte ptr", 1);
                    485: }
                    486: 
                    487: 
                    488: void emittwooperandsw (void)
                    489: {
                    490: 
                    491:        printf (" ");
                    492:        emitanoperand (2, "ds:word ptr", 1);
                    493:        printf (",");
                    494:        emitanoperand (1, "ds:word ptr", 1);
                    495: }
                    496: 
                    497: 
                    498: void emit_0_or_1_operandsl (void)
                    499: {
                    500: 
                    501:        if (tokennum == 2)
                    502:        {
                    503:                printf (" ");
                    504:                emitanoperand (1, "ds:dword ptr", 1);
                    505:        }
                    506: }
                    507: 
                    508: 
                    509: void emit_1_or_2_operandsl (void)
                    510: {
                    511:        int             j;
                    512: 
                    513:        if (tokennum == 2)
                    514:        {
                    515:                printf (" ");
                    516:                emitanoperand (1, "ds:dword ptr", 1);
                    517:        }
                    518:        else if (tokennum == 3)
                    519:        {
                    520:                printf (" ");
                    521:                emitanoperand (2, "ds:dword ptr", 1);
                    522:                printf (",");
                    523:                emitanoperand (1, "ds:dword ptr", 1);
                    524:        }
                    525:        else
                    526:        {
                    527: 
                    528:                fprintf (stderr, "Error: too many operands\n");
                    529: 
                    530:                for (j=0 ; j<tokennum ; j++)
                    531:                        fprintf (stderr, "%s\n", tokens[j]);
                    532: 
                    533:                fprintf (stderr, "\n");
                    534:                errorexit ();
                    535:        }
                    536: }
                    537: 
                    538: 
                    539: void emit_1_or_2_operandsl_vartext (char *str0, char *str1)
                    540: {
                    541:        int             j;
                    542: 
                    543:        if (tokennum == 2)
                    544:        {
                    545:                printf (" %s ", str0);
                    546:                emitanoperand (1, "ds:dword ptr", 1);
                    547:        }
                    548:        else if (tokennum == 3)
                    549:        {
                    550:                if (!strcmpi (tokens[2], "%st(0)"))
                    551:                        printf (" %s ", str0);
                    552:                else
                    553:                        printf (" %s ", str1);
                    554: 
                    555:                emitanoperand (2, "ds:dword ptr", 1);
                    556:                printf (",");
                    557:                emitanoperand (1, "ds:dword ptr", 1);
                    558:        }
                    559:        else
                    560:        {
                    561: 
                    562:                fprintf (stderr, "Error: too many operands\n");
                    563: 
                    564:                for (j=0 ; j<tokennum ; j++)
                    565:                        fprintf (stderr, "%s\n", tokens[j]);
                    566: 
                    567:                fprintf (stderr, "\n");
                    568:                errorexit ();
                    569:        }
                    570: }
                    571: 
                    572: 
                    573: void special_fdivl (void)
                    574: {
                    575: 
                    576:        emit_1_or_2_operandsl_vartext ("fdiv", "fdivr");
                    577: }
                    578: 
                    579: 
                    580: void special_fdivpl (void)
                    581: {
                    582: 
                    583:        emit_1_or_2_operandsl_vartext ("fdivp", "fdivrp");
                    584: }
                    585: 
                    586: 
                    587: void special_fdivrl (void)
                    588: {
                    589: 
                    590:        emit_1_or_2_operandsl_vartext ("fdivr", "fdiv");
                    591: }
                    592: 
                    593: 
                    594: void special_fdivrpl (void)
                    595: {
                    596: 
                    597:        emit_1_or_2_operandsl_vartext ("fdivrp", "fdivp");
                    598: }
                    599: 
                    600: 
                    601: void special_fsubl (void)
                    602: {
                    603: 
                    604:        emit_1_or_2_operandsl_vartext ("fsub", "fsubr");
                    605: }
                    606: 
                    607: 
                    608: void special_fsubpl (void)
                    609: {
                    610: 
                    611:        emit_1_or_2_operandsl_vartext ("fsubp", "fsubrp");
                    612: }
                    613: 
                    614: 
                    615: void special_fsubrl (void)
                    616: {
                    617: 
                    618:        emit_1_or_2_operandsl_vartext ("fsubr", "fsub");
                    619: }
                    620: 
                    621: 
                    622: void special_fsubrpl (void)
                    623: {
                    624: 
                    625:        emit_1_or_2_operandsl_vartext ("fsubrp", "fsubp");
                    626: }
                    627: 
                    628: 
                    629: void emit_multiple_data (void)
                    630: {
                    631:        int             i;
                    632: 
                    633:        printf (" ");
                    634: 
                    635:        for (i=1 ; i<(tokennum-1) ; i++)
                    636:        {
                    637:                emitanoperand (i, "", 0);
                    638:                printf (", ");
                    639:        }
                    640: 
                    641:        emitanoperand (i, "", 0);
                    642: }
                    643: 
                    644: 
                    645: //==============================================
                    646: 
                    647: parsefield     parsedata[] = {
                    648:        {".align", " align", 2, emitonedata},
                    649:        {".byte",  " db", -2, emit_multiple_data},
                    650:        {".data",  "", 1, datasegstart},
                    651:        {".extern"," externdef", 2, emitexterndef},
                    652:        {".globl", " public", -2, emit_multiple_data},
                    653:        {".long",  " dd", -2, emit_multiple_data},
                    654:        {".single"," dd", -2, emit_multiple_data},
                    655:        {".text",  "", 1, textsegstart},
                    656:        {"adcl",   " adc", 3, emittwooperandsl},
                    657:        {"addb",   " add", 3, emittwooperandsb},
                    658:        {"addl",   " add", 3, emittwooperandsl},
                    659:        {"andb",   " and", 3, emittwooperandsb},
                    660:        {"andl",   " and", 3, emittwooperandsl},
                    661:        {"call",   " call", 2, emitonecalldata},
                    662:        {"cmpb",   " cmp", 3, emittwooperandsb},
                    663:        {"cmpl",   " cmp", 3, emittwooperandsl},
                    664:        {"cmpw",   " cmp", 3, emittwooperandsw},
                    665:        {"decl",   " dec", 2, emitoneoperandl},
                    666:        {"decw",   " dec", 2, emitoneoperandw},
                    667:        {"divl",   " div", 2, emitoneoperandl},
                    668:        {"fadd",   " fadd", -2, emit_1_or_2_operandsl},
                    669:        {"faddp",  " faddp", -2, emit_1_or_2_operandsl},
                    670:        {"faddps", " faddp", -2, emit_1_or_2_operandsl},
                    671:        {"fadds",  " fadd", -2, emit_1_or_2_operandsl},
                    672:        {"fcom",   " fcom", 2, emitoneoperandl},
                    673:        {"fcoms",  " fcom", 2, emitoneoperandl},
                    674:        {"fcomp",  " fcomp", 2, emitoneoperandl},
                    675:        {"fcomps", " fcomp", 2, emitoneoperandl},
                    676:        {"fdiv",   "", -2, special_fdivl}, 
                    677:        {"fdivp",  "", -2, special_fdivpl}, 
                    678:        {"fdivr",  "", -2, special_fdivrl},
                    679:        {"fdivrp", "", -2, special_fdivrpl},
                    680:        {"fdivrs", "", -2, special_fdivrl},
                    681:        {"fildl",  " fild", 2, emitoneoperandl},
                    682:        {"fistl",  " fist", 2, emitoneoperandl},
                    683:        {"fistpl", " fistp", 2, emitoneoperandl},
                    684:        {"fld",    " fld", 2, emitoneoperandl},
                    685:        {"fldcw",  " fldcw", 2, emitoneoperandw},
                    686:        {"fldenv", " fldenv", 2, emitoneoperandl},
                    687:        {"flds",   " fld", 2, emitoneoperandl},
                    688:        {"fmul",   " fmul", -2, emit_1_or_2_operandsl},
                    689:        {"fmulp",  " fmulp", -2, emit_1_or_2_operandsl},
                    690:        {"fmulps", " fmulp", -2, emit_1_or_2_operandsl},
                    691:        {"fmuls",  " fmul", -2, emit_1_or_2_operandsl},
                    692:        {"fnstcw", " fnstcw", 2, emitoneoperandw},
                    693:        {"fnstenv"," fnstenv", 2, emitoneoperandl},
                    694:        {"fnstsw", " fnstsw", 2, emitoneoperandw},
                    695:        {"fstp",   " fstp", 2, emitoneoperandl},
                    696:        {"fstps",  " fstp", 2, emitoneoperandl},
                    697:        {"fsts",   " fst", 2, emitoneoperandl},
                    698:        {"fsubr",  "", -2, special_fsubrl},
                    699:        {"fsubrp", "", -2, special_fsubrpl},
                    700:        {"fsubrs", "", -2, special_fsubrl},
                    701:        {"fsub",   "", -2, special_fsubl},
                    702:        {"fsubp",  "", -2, special_fsubpl},
                    703:        {"fsubps", "", -2, special_fsubpl},
                    704:        {"fsubs",  "", -2, special_fsubl},
                    705:        {"fxch",   " fxch", 2, emitoneoperandl},
                    706:        {"imull",  " imul", -2, emit_1_or_2_operandsl},
                    707:        {"incl",   " inc", 2, emitoneoperandl},
                    708:        {"ja",     " ja", 2, emitonedata},
                    709:        {"jae",    " jae", 2, emitonedata},
                    710:        {"jb",     " jb", 2, emitonedata},
                    711:        {"jbe",    " jbe", 2, emitonedata},
                    712:        {"jc",     " jc", 2, emitonedata},
                    713:        {"je",     " je", 2, emitonedata},
                    714:        {"jg",     " jg", 2, emitonedata},
                    715:        {"jge",    " jge", 2, emitonedata},
                    716:        {"jl",     " jl", 2, emitonedata},
                    717:        {"jle",    " jle", 2, emitonedata},
                    718:        {"jmp",    " jmp", 2, emitonejumpdata},
                    719:        {"jna",    " jna", 2, emitonedata},
                    720:        {"jnae",   " jnae", 2, emitonedata},
                    721:        {"jnb",    " jnb", 2, emitonedata},
                    722:        {"jnbe",   " jnbe", 2, emitonedata},
                    723:        {"jnc",    " jnc", 2, emitonedata},
                    724:        {"jne",    " jne", 2, emitonedata},
                    725:        {"jng",    " jng", 2, emitonedata},
                    726:        {"jnge",   " jnge", 2, emitonedata},
                    727:        {"jnl",    " jnl", 2, emitonedata},
                    728:        {"jnle",   " jnle", 2, emitonedata},
                    729:        {"jns",    " jns", 2, emitonedata},
                    730:        {"jnz",    " jnz", 2, emitonedata},
                    731:        {"js",     " js", 2, emitonedata},
                    732:        {"jz",     " jz", 2, emitonedata},
                    733:        {"leal",   " lea", 3, emittwooperandsl},
                    734:        {"movb",   " mov", 3, emittwooperandsb},
                    735:        {"movl",   " mov", 3, emittwooperandsl},
                    736:        {"movw",   " mov", 3, emittwooperandsw},
                    737:        {"negl",   " neg", 2, emitoneoperandl},
                    738:        {"orb",    " or", 3, emittwooperandsb},
                    739:        {"orl",    " or", 3, emittwooperandsl},
                    740:        {"popl",   " pop", 2, emitoneoperandl},
                    741:        {"pushl",  " push", 2, emitoneoperandl},
                    742:        {"ret",    " ret", -1, emit_0_or_1_operandsl},
                    743:        {"rorl",   " ror", 3, emittwooperandsl},
                    744:        {"sarl",   " sar", 3, emittwooperandsl},
                    745:        {"sbbl",   " sbb", 3, emittwooperandsl},
                    746:        {"shll",   " shl", 3, emittwooperandsl},
                    747:        {"shrl",   " shr", 3, emittwooperandsl},        
                    748:        {"subl",   " sub", 3, emittwooperandsl},
                    749:        {"testb",  " test", 3, emittwooperandsb},
                    750:        {"testl",  " test", 3, emittwooperandsl},
                    751:        {"xorb",   " xor", 3, emittwooperandsb},
                    752:        {"xorl",   " xor", 3, emittwooperandsl},
                    753: };
                    754: 
                    755: int    numparse = sizeof (parsedata) / sizeof (parsedata[0]);
                    756: 
                    757: //==============================================
                    758: 
                    759: void errorexit (void)
                    760: {
                    761:        fprintf (stderr, "In line: %d, out line: %d\n", inline, outline);
                    762:        exit (1);
                    763: }
                    764: 
                    765: 
                    766: tokenstat whitespace (char c)
                    767: {
                    768:        if (c == '\n')
                    769:                return LINE_DONE;
                    770: 
                    771:        if ((c <= ' ') ||
                    772:                (c > 127) ||
                    773:                (c == ','))
                    774:        {
                    775:                return WHITESPACE;
                    776:        }
                    777: 
                    778:        return NOT_WHITESPACE;
                    779: }
                    780: 
                    781: 
                    782: int gettoken (void)
                    783: {
                    784:        char            c;
                    785:        int                     count, parencount;
                    786:        tokenstat       stat;
                    787: 
                    788:        do
                    789:        {
                    790:                if ((c = getchar ()) == EOF)
                    791:                        return FILE_DONE;
                    792: 
                    793:                if ((stat = whitespace (c)) == LINE_DONE)
                    794:                        return LINE_DONE;
                    795:        } while (stat == WHITESPACE);
                    796: 
                    797:        token[0] = c;
                    798:        count = 1;
                    799: 
                    800:        if (c == '~')
                    801:        {
                    802:                count--;
                    803:                token[count++] = 'n';
                    804:                token[count++] = 'o';
                    805:                token[count++] = 't';
                    806:                token[count++] = ' ';
                    807:        }
                    808: 
                    809:        if (c == '(')
                    810:        {
                    811:                do
                    812:                {
                    813:                        if ((c = getchar ()) == EOF)
                    814:                        {
                    815:                                fprintf (stderr, "EOF in middle of parentheses\n");
                    816:                                errorexit ();
                    817:                        }
                    818: 
                    819:                        token[count++] = c;
                    820: 
                    821:                } while (c != ')');
                    822:        }
                    823:        
                    824:        for ( ;; )
                    825:        {
                    826:                if ((c = getchar ()) == EOF)
                    827:                {
                    828:                        token[count] = 0;
                    829:                        return TOKEN_AVAILABLE;
                    830:                }
                    831: 
                    832:                if (whitespace (c) == LINE_DONE)
                    833:                {
                    834:                        if (ungetc (c, stdin) == EOF)
                    835:                        {
                    836:                                fprintf (stderr, "Couldn't unget character\n");
                    837:                                errorexit ();
                    838:                        }
                    839: 
                    840:                        token[count] = 0;
                    841:                        return TOKEN_AVAILABLE;
                    842:                }
                    843: 
                    844:                if (whitespace (c) == WHITESPACE)
                    845:                {
                    846:                        token[count] = 0;
                    847:                        return TOKEN_AVAILABLE;
                    848:                }
                    849: 
                    850:                if (count >= MAX_TOKEN_LENGTH)
                    851:                {
                    852:                        fprintf (stderr, "Error: token too long\n");
                    853:                        errorexit ();
                    854:                }
                    855: 
                    856:                token[count++] = c;
                    857: 
                    858:                if (c == '~')
                    859:                {
                    860:                        count--;
                    861:                        token[count++] = 'n';
                    862:                        token[count++] = 'o';
                    863:                        token[count++] = 't';
                    864:                        token[count++] = ' ';
                    865:                }
                    866:                else if (c == '(')
                    867:                {
                    868:                        parencount = 1;
                    869: 
                    870:                        do
                    871:                        {
                    872:                                if ((c = getchar ()) == EOF)
                    873:                                {
                    874:                                        fprintf (stderr, "EOF in middle of parentheses\n");
                    875:                                        errorexit ();
                    876:                                }
                    877: 
                    878:                                if (c == '(')
                    879:                                        parencount++;
                    880:                                else if (c == ')')
                    881:                                        parencount--;
                    882: 
                    883:                                if (c == '~')
                    884:                                {
                    885:                                        token[count++] = 'n';
                    886:                                        token[count++] = 'o';
                    887:                                        token[count++] = 't';
                    888:                                        token[count++] = ' ';
                    889:                                }
                    890:                                else
                    891:                                {
                    892:                                        token[count++] = c;
                    893:                                }
                    894: 
                    895:                        } while ((c != ')') || (parencount > 0));
                    896:                }
                    897:        }
                    898: }
                    899: 
                    900: 
                    901: tokenstat parseline (void)
                    902: {
                    903:        tokenstat       stat;
                    904:        int                     i, j, firsttoken, labelfound;
                    905:        int                     mnemfound;
                    906: 
                    907:        firsttoken = 1;
                    908:        tokennum = 0;
                    909:        labelfound = 0;
                    910: 
                    911:        for ( ;; )
                    912:        {
                    913:                token = tokens[tokennum];
                    914:                stat = gettoken ();
                    915: 
                    916:                switch (stat)
                    917:                {
                    918:                case FILE_DONE:
                    919:                        return FILE_DONE;
                    920: 
                    921:                case LINE_DONE:
                    922:                        if (!firsttoken && tokennum)
                    923:                        {
                    924:                                mnemfound = 0;
                    925: 
                    926:                                for (i=0 ; i<numparse; i++)
                    927:                                {
                    928:                                        if (!strcmpi (tokens[0], parsedata[i].text))
                    929:                                        {
                    930:                                                if (((parsedata[i].numtokens > 0) &&
                    931:                                                         (parsedata[i].numtokens != tokennum)) ||
                    932:                                                        ((parsedata[i].numtokens < 0) &&
                    933:                                                         (tokennum < -parsedata[i].numtokens)))
                    934:                                                {
                    935:                                                        fprintf (stderr, "mismatched number of tokens\n");
                    936: 
                    937:                                                        for (j=0 ; j<tokennum ; j++)
                    938:                                                                fprintf (stderr, "%s\n", tokens[j]);
                    939: 
                    940:                                                        fprintf (stderr, "\n");
                    941:                                                        errorexit ();
                    942:                                                }
                    943: 
                    944:                                                printf ("%s", parsedata[i].emit);
                    945:                                                (*parsedata[i].parsefunc) ();
                    946: 
                    947:                                                mnemfound = 1;
                    948:                                                break;
                    949:                                        }
                    950:                                }
                    951: 
                    952:                                if (!mnemfound)
                    953:                                {
                    954:                                        fprintf (stderr, "Error: unknown mnemonic\n");
                    955: 
                    956:                                        for (j=0 ; j<tokennum ; j++)
                    957:                                                fprintf (stderr, "%s\n", tokens[j]);
                    958: 
                    959:                                        fprintf (stderr, "\n");
                    960:                                        errorexit ();
                    961:                                }
                    962:                        }
                    963: 
                    964:                        if (!firsttoken)
                    965:                        {
                    966:                                if ((currentseg == DATASEG) && labelfound && !tokennum)
                    967:                                        printf (":\n");
                    968:                                else
                    969:                                        printf ("\n");
                    970: 
                    971:                                outline++;
                    972:                        }
                    973:                        return PARSED_OKAY;
                    974: 
                    975:                case TOKEN_AVAILABLE:
                    976:                        if (firsttoken)
                    977:                        {
                    978:                                if (token[strlen(token) - 1] == ':')
                    979:                                {
                    980:                                        labelfound = 1;
                    981: 
                    982:                                        if (currentseg == DATASEG)
                    983:                                        {
                    984:                                                token[strlen(token) - 1] = 0;
                    985:                                                printf ("%s", token);
                    986:                                        }
                    987:                                        else if (currentseg == TEXTSEG)
                    988:                                        {
                    989:                                                printf ("%s", token);
                    990:                                        }
                    991:                                        else
                    992:                                        {
                    993:                                                fprintf (stderr, "Error: not in segment block\n");
                    994:                                                errorexit ();
                    995:                                        }
                    996: 
                    997:                                        firsttoken = 0;
                    998:                                        break;
                    999:                                }
                   1000:                        }
                   1001: 
                   1002:                        firsttoken = 0;
                   1003: 
                   1004:                        if (tokennum >= MAX_TOKENS)
                   1005:                        {
                   1006:                                fprintf (stderr, "Error: too many tokens\n");
                   1007:                                exit (0);
                   1008:                        }
                   1009: 
                   1010:                        tokennum++;
                   1011: 
                   1012:                        break;
                   1013: 
                   1014:                default:
                   1015:                        fprintf (stderr, "Error: unknown tokenstat %d\n", stat);
                   1016:                        exit (0);
                   1017:                }
                   1018:        }
                   1019: }
                   1020: 
                   1021: 
                   1022: void main (int argc, char **argv)
                   1023: {
                   1024:        tokenstat       stat;
                   1025: 
                   1026:        printf (" .386P\n"
                   1027:             " .model FLAT\n");
                   1028:        inline = 1;
                   1029:        outline = 3;
                   1030: 
                   1031:        for ( ;; )
                   1032:        {
                   1033:                stat = parseline ();
                   1034:                inline++;
                   1035: 
                   1036:                switch (stat)
                   1037:                {
                   1038:                case FILE_DONE:
                   1039:                        if (currentseg == TEXTSEG)
                   1040:                                printf ("_TEXT ENDS\n");
                   1041:                        else if (currentseg == DATASEG)
                   1042:                                printf ("_DATA ENDS\n");
                   1043: 
                   1044:                        printf (" END\n");
                   1045:                        exit (0);
                   1046:                
                   1047:                case PARSED_OKAY:
                   1048:                        break;
                   1049: 
                   1050:                default:
                   1051:                        fprintf (stderr, "Error: unknown tokenstat %d\n", stat);
                   1052:                        exit (0);
                   1053:                }
                   1054:        }
                   1055: }
                   1056: 

unix.superglobalmegacorp.com

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