⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 io.c

📁 一个C style Assembler的source code
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdlib.h>#include <stdio.h>#include <string.h>#include <ctype.h>#include <stdarg.h>#include "io.h"#include "op.h" extern int Active; /* SKIP LISTS are used to implement the symbol table */ char *CopyS(char *S) {   char *NewS;   if (S == 0) return 0;   NewS = Allocate(strlen(S) + 1);   strcpy(NewS, S);   return NewS;} int CompS(char *A, char *B) {   if (A == 0) return (B == 0)? 0: +1;   if (B == 0) return -1;   for (; *A != '\0'; A++, B++) {      int Diff = tolower(*A) - tolower(*B);      if (Diff < 0) return -1;      if (Diff > 0) return +1;   }   return (*B == '\0')? 0: -1;} static int Random(void) {   static byte B = 0, X = 0;   register int L = 0, D;   while (1) {      if (X == 0) X = 4, B = rand()&0xff;      D = B&3, B >>= 2, X--;      if (D) return L;      L++;   }} #define MAX_BREADTH 16Symbol NIL;static Symbol Path[MAX_BREADTH];static int Breadth; static Symbol Form(int B, char *Name) {   Symbol N = (Symbol)malloc(sizeof *N + B*sizeof(Symbol));   if (N == 0) fprintf(stderr, "Out of memory.\n"), exit(1);   N->Name = CopyS(Name),   N->Defined = N->Global = N->Variable = N->Address = N->Map = 0;   return N;} #include <sys/types.h>#include <sys/timeb.h> void SymInit(void) {   struct timeb T; int K;   ftime(&T); srand((unsigned int)(T.time ^ T.millitm)&0xffff);   NIL = Form(MAX_BREADTH - 1, 0);   for (K = 0; K < MAX_BREADTH; K++) NIL->Next[K] = NIL;   Breadth = 0;} int Next, Value;int Line, StartLine; Symbol LookUp(char *Name) {   int K, B; Symbol P, Q;   if (!Active) return 0;   for (K = Breadth, P = NIL; K >= 0; K--) {      Q = P->Next[K];      while (CompS(Q->Name, Name) < 0) P = Q, Q = Q->Next[K];      Path[K] = P;   }   if (CompS(Q->Name, Name) == 0) return Q;   K = Random(); if (K > Breadth) K = ++Breadth, Path[K] = NIL;   Q = Form(K, Name);   for (; K >= 0; K--) Q->Next[K] = Path[K]->Next[K], Path[K]->Next[K] = Q;   return Q;}#define LINE_MAX 200char Text[LINE_MAX]; static char *U; #define INCLUDE_MAX 5struct {   word Path; long Loc; int Next, Line;} IS[INCLUDE_MAX], *ISP;static FILE *InF; FILE *OutF;char **FileTab; long Files;int StartF, CurF;static int FileMax; void FileInit(void) {   ISP = IS - 1, FileTab = 0, Files = 0, FileMax = 0;} static byte ERRORS = 0;char InSeg = 0;void ERROR(const char *Format, ...) {   va_list AP;   if (InSeg) printf("%s: [%d] ", FileTab[StartF], StartLine);   va_start(AP, Format);   vprintf(Format, AP); putchar('\n');   va_end(AP);   if (++ERRORS >= 24) printf("Too many errors.  Aborting.\n"), exit(1);}  void FATAL(const char *Format, ...) {   va_list AP;   if (InSeg) printf("%s: [%d] ", FileTab[StartF], StartLine);   va_start(AP, Format);   vprintf(Format, AP); putchar('\n');   va_end(AP);   exit(1);} void CHECK(void) {   if (ERRORS > 0) printf("Errors present.  Assembly stopped.\n"), exit(1);} byte GetB(FILE *FP) {   int A;   A = fgetc(FP); if (A == EOF) FATAL("Unexpected EOF.");   return A&0xff;} word GetW(FILE *FP) {   int A, B;   A = fgetc(FP); if (A == EOF) FATAL("Unexpected EOF.");   B = fgetc(FP); if (B == EOF) FATAL("Unexpected EOF.");   return (A&0xff) << 8 | B&0xff;} unsigned long GetL(FILE *FP) {   int A, B, C, D;   A = fgetc(FP); if (A == EOF) FATAL("Unexpected EOF.");   B = fgetc(FP); if (B == EOF) FATAL("Unexpected EOF.");   C = fgetc(FP); if (C == EOF) FATAL("Unexpected EOF.");   D = fgetc(FP); if (D == EOF) FATAL("Unexpected EOF.");   return (A&0xff) << 24 | (B&0xff) << 16 | (C&0xff) << 8 | D&0xff;} void PutB(byte B, FILE *FP) { fputc(B, FP); } void PutW(word W, FILE *FP) {   char A = (W >> 8)&0xff, B = W&0xff;   fputc(A, FP), fputc(B, FP);} void PutL(unsigned long L, FILE *FP) {   char A = (L >> 24)&0xff, B = (L >> 16)&0xff, C = (L >> 8)&0xff, D = L&0xff;   fputc(A, FP), fputc(B, FP), fputc(C, FP), fputc(D, FP);} void *Allocate(unsigned Size) {   void *X;   if (Size == 0) return 0;   X = malloc(Size); if (X == 0) FATAL("Out of memory.");   return X;} void OpenF(char *Name) {   if (!Active) return;   if (ISP >= IS + INCLUDE_MAX - 1) FATAL("Too many nested include files.");   if (ISP >= IS) {      ISP->Loc = ftell(InF);      if (ISP->Loc == -1L)         FATAL("Could not save %s's position.", FileTab[CurF]);      fclose(InF);      ISP->Next = Next, ISP->Line = Line, ISP->Path = CurF;   }   if (Files >= FileMax) {      FileMax += 4;      FileTab = (char **)realloc(FileTab, FileMax * sizeof *FileTab);      if (FileTab == 0) FATAL("Out of memory.");   }   ISP++, CurF = Files, FileTab[Files++] = CopyS(Name);   StartLine = Line = 1;   InF = fopen(Name, "r");   if (InF == 0) FATAL("Cannot open %s", Name);   Next = fgetc(InF);} #define SEG_MAX 0x20struct Segment SegTab[SEG_MAX], *SegP;unsigned long LOC; #define GAP_MAX 0x100struct Gap GapTab[GAP_MAX], *GapP; struct AddrCard AddrTab[TYPES] = {   { 0, 0xffff, 1 },  /* CODE */   { 0, 0xffff, 0 },  /* XDATA */   { 0, 0xff, 0 },    /* DATA */   { 0x80, 0xff, 0 }, /* SFR */   { 0, 0xff, 0 }     /* BIT */};static struct AddrCard *AdP; Symbol Sym; static Symbol BTab[10], FTab[10];static Symbol MakeLabel(void) {   static unsigned long LAB = 0L; static char Buf[10];   sprintf(Buf, "#%x", LAB++);   return LookUp(Buf);} void SegInit(void) {   int I, D;   for (SegP = SegTab, AdP = AddrTab, I = 0; I < TYPES; AdP++, I++, SegP++) {      if (SegP >= SegTab + SEG_MAX) FATAL("Too many segments.");      SegP->Type = I, SegP->Rel;      SegP->Base = 0, SegP->Size = 0, SegP->Loc = ftell(OutF);   }   AdP = AddrTab; InSeg = 1;   SegP->Type = 0, SegP->Rel = 1,   SegP->Line = StartLine, SegP->File = StartF,   SegP->Base = 0, SegP->Size = 0, SegP->Loc = ftell(OutF);   LOC = 0;   for (D = 0; D < 10; D++) BTab[0] = FTab[0] = 0;   GapP = GapTab;} void StartSeg(byte Type, byte Rel, word Base) {   int D;   if (!Active) return;   if (SegP >= SegTab + SEG_MAX) FATAL("Too many segments.");   if (Type > sizeof AddrTab/sizeof *AddrTab)      FATAL("Undefined segment type.");   AdP = AddrTab + Type;   if (!Rel && (Base < AdP->Lo || Base > AdP->Hi))      FATAL("Address %u out of range", Base);   InSeg = 1;   SegP->Type = Type, SegP->Rel = Rel,   SegP->Line = StartLine, SegP->File = StartF,   SegP->Base = Base, SegP->Size = 0, SegP->Loc = ftell(OutF);   LOC = 0;   for (D = 0; D < 10; D++) BTab[0] = FTab[0] = 0;} void EndSeg(void) {   int D;   if (!Active) return;   for (D = 0; D < 10; D++)      if (FTab[D] != 0) ERROR("Undefined label %d", D);   SegP->Size = (word)LOC;   if (SegP->Size > 0) SegP++;   InSeg = 0;} void Space(word Rel) {   unsigned long Addr;   if (!Active) return;   if (AdP->ReadOnly) {      if (GapP >= GapTab + GAP_MAX) FATAL("Too many gaps.");      GapP->Seg = SegP, GapP->Offset = LOC, GapP->Size = Rel;      GapP++;   }   LOC += Rel;   Addr = SegP->Base + LOC;   if (!SegP->Rel && Addr > AdP->Hi + 1) FATAL("Address %u out of range", Addr);} void PByte(byte B) {   unsigned long Addr;   if (!Active) return;   if (!AdP->ReadOnly) FATAL("Attempting to write to a non-code segment.");   LOC++; Addr = SegP->Base + LOC;   if (!SegP->Rel && Addr > AdP->Hi + 1) FATAL("Address %u out of range", Addr);   fputc(B, OutF);} void PString(char *S) {   if (!Active) return;   for (; *S != '\0'; S++) PByte(*S);} static void Get(void) {   int Ch;   if (Next == EOF) {      while (Next == EOF && ISP > IS) {         fclose(InF); ISP--;         Next = ISP->Next, Line = ISP->Line, CurF = ISP->Path;         InF = fopen(FileTab[CurF], "r");         if (InF == 0) FATAL("Cannot reopen %s", FileTab[CurF]);         if (fseek(InF, ISP->Loc, SEEK_SET) != 0) {            fclose(InF);            FATAL("Could not restore %s's position.", FileTab[CurF]);         }      }      if (Next == EOF) fclose(InF), Next = 0;      *U++ = ' ';   } else {      if (Next == '\n') Line++;      *U++ = Next; Next = fgetc(InF);   }} typedef struct {   char *Name; Lexical Tag; int Value;} Card;static Card Reserved[] = {   { "ds", RB, 0 }, { "rb", RB, 0 }, { "rw", RW, 0 },   { "byte", DB, 0 }, { "word", DW, 0 }, { "db", DB, 0 }, { "dw", DW, 0 },   { "seg", SEG, 0 }, { "end", END, 0 },   { "org", ORG, 0 }, { "at", ORG, 0 }, { "equ", EQU, 0 }, { "set", SET, 0 },   { "include", INCLUDE, 0 }, { "global", GLOBAL, 0 }, { "public", GLOBAL, 0 },   { "extern", EXTERN, 0 }, { "if", IF, 0 }, { "else", ELSE, 0 },   { "high", HIGH, 0 }, { "low", LOW, 0 }, { "by", BY, 0 },   { "code", TYPE, CODE }, { "xdata", TYPE, XDATA },   { "bit", TYPE, BIT }, { "sfr", TYPE, SFR }, { "data", TYPE, DATA },   { "a", REGISTER, ACC }, { "ab", REGISTER, AB }, { "c", REGISTER, CY },   { "dptr", REGISTER, DPTR }, { "pc", REGISTER, PC },   { "r0", REGISTER, R0 }, { "r1", REGISTER, R1 },   { "r2", REGISTER, R2 }, { "r3", REGISTER, R3 },   { "r4", REGISTER, R4 }, { "r5", REGISTER, R5 },   { "r6", REGISTER, R6 }, { "r7", REGISTER, R7 }}; #define ELEMENTS(Arr) (sizeof(Arr)/sizeof(Arr[0])) static Lexical FindKey(char *Name) {   Code *CP; Card *C;   static Card *EndR = Reserved + ELEMENTS(Reserved);   for (CP = CodeTab; CP->Name != 0; CP++)      if (CompS(Name, CP->Name) == 0) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -