1/* 2Copyright (C) 1996-1997 Id Software, Inc. 3 4This program is free software; you can redistribute it and/or 5modify it under the terms of the GNU General Public License 6as published by the Free Software Foundation; either version 2 7of the License, or (at your option) any later version. 8 9This program is distributed in the hope that it will be useful, 10but WITHOUT ANY WARRANTY; without even the implied warranty of 11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 13See the GNU General Public License for more details. 14 15You should have received a copy of the GNU General Public License 16along with this program; if not, write to the Free Software 17Foundation, 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 32typedef enum {NOT_WHITESPACE, WHITESPACE, TOKEN_AVAILABLE, LINE_DONE, FILE_DONE, PARSED_OKAY} tokenstat; 33typedef enum {NOSEG, DATASEG, TEXTSEG} segtype; 34 35int tokennum; 36int inline, outline; 37 38char *token; 39char tokens[MAX_TOKENS][MAX_TOKEN_LENGTH+1]; 40 41segtype currentseg = NOSEG; 42 43typedef struct { 44 char *text; 45 char *emit; 46 int numtokens; 47 void (*parsefunc) (void); 48} parsefield; 49 50 51void errorexit (void); 52 53 54//============================================== 55 56typedef struct { 57 char *text; 58 char *emit; 59 int len; 60} regdesc; 61 62regdesc 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 97int numregs = sizeof (reglist) / sizeof (reglist[0]); 98 99//============================================== 100 101 102void 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 317void 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 331void 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 345void 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 356void emitonedata (void) 357{ 358 359 printf (" %s", tokens[1]); 360} 361 362 363void 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 397void 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 431void emitexterndef (void) 432{ 433 434 printf (" %s:dword", tokens[1]); 435} 436 437 438void nooperands (void) 439{ 440 441} 442 443 444void emitoneoperandl (void) 445{ 446 447 printf (" "); 448 emitanoperand (1, "ds:dword ptr", 1); 449} 450 451 452void emitoneoperandb (void) 453{ 454 455 printf (" "); 456 emitanoperand (1, "ds:byte ptr", 1); 457} 458 459 460void emitoneoperandw (void) 461{ 462 463 printf (" "); 464 emitanoperand (1, "ds:word ptr", 1); 465} 466 467 468void 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 478void 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 488void 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 498void 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 509void 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 539void 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 573void special_fdivl (void) 574{ 575 576 emit_1_or_2_operandsl_vartext ("fdiv", "fdivr"); 577} 578 579 580void special_fdivpl (void) 581{ 582 583 emit_1_or_2_operandsl_vartext ("fdivp", "fdivrp"); 584} 585 586 587void special_fdivrl (void) 588{ 589 590 emit_1_or_2_operandsl_vartext ("fdivr", "fdiv"); 591} 592 593 594void special_fdivrpl (void) 595{ 596 597 emit_1_or_2_operandsl_vartext ("fdivrp", "fdivp"); 598} 599 600 601void special_fsubl (void) 602{ 603 604 emit_1_or_2_operandsl_vartext ("fsub", "fsubr"); 605} 606 607 608void special_fsubpl (void) 609{ 610 611 emit_1_or_2_operandsl_vartext ("fsubp", "fsubrp"); 612} 613 614 615void special_fsubrl (void) 616{ 617 618 emit_1_or_2_operandsl_vartext ("fsubr", "fsub"); 619} 620 621 622void special_fsubrpl (void) 623{ 624 625 emit_1_or_2_operandsl_vartext ("fsubrp", "fsubp"); 626} 627 628 629void 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 647parsefield 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 755int numparse = sizeof (parsedata) / sizeof (parsedata[0]); 756 757//============================================== 758 759void errorexit (void) 760{ 761 fprintf (stderr, "In line: %d, out line: %d\n", inline, outline); 762 exit (1); 763} 764 765 766tokenstat 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 782int 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 901tokenstat 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 1022void 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 1057