📄 das.c
字号:
#include <stdio.h>typedef unsigned char byte;typedef unsigned int word;byte Arg[3];word PC; byte Generating;byte Ref[0x4000], Hex[0x4000];#define ENTRY 0x80#define OP 0x40#define ARG 0x20#define LINKS 0x1fword Paged(byte P) { return PC&0xf800 | (Arg[0]&0xe0) << 3 | P;};word Relative(byte R) { return PC + (signed char)R;};word Entries[0x100], *EP = Entries;void PUSH(word Address) { byte B = Ref[Address]&LINKS; if (Ref[Address]&ARG) { fprintf(stderr, "Entry into ARG at %04x.\n", PC); return; } if (++B <= LINKS) Ref[Address] = Ref[Address]&~LINKS | B; if (Ref[Address]&ENTRY) return; Ref[Address] |= ENTRY; if (Ref[Address]&OP) return; if (EP - Entries == 0x100) { fprintf(stderr, "Too many entries, PC = %04x.\n", PC); exit(1); } *EP++ = Address;};byte Xs[0x100] = { 1, 14, 15, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, 6, 7, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, 14, 9, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, 6, 9, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 14, 2, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, 2, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 14, 2, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, 2, 25, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,14, 14, 2, 1, 1, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 6, 2, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 14, 2, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 1, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 14, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 6, 2, 1, 1, 7, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6, 1, 14, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};char *Ns[0x100] = {"nop", "ajmp %P", "ljmp %L", "rr A", "inc A", "inc %D", "inc %i", "inc %i", "inc %n", "inc %n", "inc %n", "inc %n", "inc %n", "inc %n", "inc %n", "inc %n","jbc %B, %R", "acall %P", "lcall %L", "rrc A", "dec A", "dec %D", "dec %i", "dec %i", "dec %n", "dec %n", "dec %n", "dec %n", "dec %n", "dec %n", "dec %n", "dec %n","jb %B, %R", "ajmp %P", "ret", "rl A", "add A, %I", "add A, %D", "add A, %i", "add A, %i", "add A, %n", "add A, %n", "add A, %n", "add A, %n", "add A, %n", "add A, %n", "add A, %n", "add A, %n","jnb %B, %R", "acall %P", "reti", "rlc A", "addc A, %I", "addc A, %D", "addc A, %i", "addc A, %i", "addc A, %n", "addc A, %n", "addc A, %n", "addc A, %n", "addc A, %n", "addc A, %n", "addc A, %n", "addc A, %n","jc %R", "ajmp %P", "orl %D, A", "orl %D, %I", "orl A, %I", "orl A, %D", "orl A, %i", "orl A, %i", "orl A, %n", "orl A, %n", "orl A, %n", "orl A, %n", "orl A, %n", "orl A, %n", "orl A, %n", "orl A, %n","jnc %R", "acall %P", "anl %D, A", "anl %D, %I", "anl A, %I", "anl A, %D", "anl A, %i", "anl A, %i", "anl A, %n", "anl A, %n", "anl A, %n", "anl A, %n", "anl A, %n", "anl A, %n", "anl A, %n", "anl A, %n","jz %R", "ajmp %P", "xrl %D, A", "xrl %D, %I", "xrl A, %I", "xrl A, %D", "xrl A, %i", "xrl A, %i", "xrl A, %n", "xrl A, %n", "xrl A, %n", "xrl A, %n", "xrl A, %n", "xrl A, %n", "xrl A, %n", "xrl A, %n","jnz %R", "acall %P", "orl C, %B", "jmp @A+DPTR", "mov A, %I", "mov %D, %I", "mov %i, %I", "mov %i, %I", "mov %n, %I", "mov %n, %I", "mov %n, %I", "mov %n, %I", "mov %n, %I", "mov %n, %I", "mov %n, %I", "mov %n, %I","sjmp %R", "ajmp %P", "anl C, %B", "movc A, @A+PC", "div AB", "mov %2D, %1D", "mov %D, %i", "mov %D, %i", "mov %D, %n", "mov %D, %n", "mov %D, %n", "mov %D, %n", "mov %D, %n", "mov %D, %n", "mov %D, %n", "mov %D, %n","mov DPTR, %W", "acall %P", "mov %B, C", "movc A, @A+DPTR", "subb A, %I", "subb A, %D", "subb A, %i", "subb A, %i", "subb A, %n", "subb A, %n", "subb A, %n", "subb A, %n", "subb A, %n", "subb A, %n", "subb A, %n", "subb A, %n","orl C, /%B", "ajmp %P", "mov C, %B", "inc DPTR", "mul AB", "ERROR", "mov %i, %D", "mov %i, %D", "mov %n, %D", "mov %n, %D", "mov %n, %D", "mov %n, %D", "mov %n, %D", "mov %n, %D", "mov %n, %D", "mov %n, %D","anl C, /%B", "acall %P", "cpl %B", "cpl C", "cjne A, %I, %R", "cjne A, %D, %R", "cjne %i, %I, %R", "cjne %i, %I, %R", "cjne %n, %I, %R", "cjne %n, %I, %R", "cjne %n, %I, %R", "cjne %n, %I, %R", "cjne %n, %I, %R", "cjne %n, %I, %R", "cjne %n, %I, %R", "cjne %n, %I, %R","push %D", "ajmp %P", "clr %B", "clr C", "swap A", "xch A, %D", "xch A, %i", "xch A, %i", "xch A, %n", "xch A, %n", "xch A, %n", "xch A, %n", "xch A, %n", "xch A, %n", "xch A, %n", "xch A, %n","pop %D", "acall %P", "setb %B", "setb C", "da A", "djnz %D, %R", "xchd A, %i", "xchd A, %i", "djnz %n, %R", "djnz %n, %R", "djnz %n, %R", "djnz %n, %R", "djnz %n, %R", "djnz %n, %R", "djnz %n, %R", "djnz %n, %R","movx A, @DPTR", "ajmp %P", "movx A, @R0", "movx A, @R1", "clr A", "mov A, %D", "mov A, %i", "mov A, %i", "mov A, %n", "mov A, %n", "mov A, %n", "mov A, %n", "mov A, %n", "mov A, %n", "mov A, %n", "mov A, %n","movx @DPTR, A", "acall %P", "movx @R0, A", "movx @R1, A", "cpl A", "mov %D, A", "mov %i, A", "mov %i, A", "mov %n, A", "mov %n, A", "mov %n, A", "mov %n, A", "mov %n, A", "mov %n, A", "mov %n, A", "mov %n, A"};void PrintByte(byte B) { if (B >= 0xa0) putchar('0'); printf("%02xh", B);}void PrintWord(word W) { if (W >= 0xa000) putchar('0'); printf("%04xh", W);}char *SFRs[0x80] = { "P0", "SP", "DPL", "DPH", 0, 0, 0, "PCON", "TCON", "TMOD", "TL0", "TL1", "TH0", "TH1", 0, 0, "P1", 0, 0, 0, 0, 0, 0, 0, "SCON", "SBUF", 0, 0, 0, 0, 0, 0, "P2", 0, 0, 0, 0, 0, 0, 0, "IE", 0, 0, 0, 0, 0, 0, 0, "P3", 0, 0, 0, 0, 0, 0, 0, "IP", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "T2CON", 0, "RCAP2L", "RCAP2H", "TL2", "TH2", 0, 0, "PSW", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "ACC", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "B", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,};void PrintData(byte D) { /* THIS ASSUMES THE 8052 */ if (!Generating) return; if (D < 0x80 || SFRs[D - 0x80] == 0) { PrintByte(D); return; } printf(SFRs[D - 0x80]);}char *Bits[0x80] = { 0, 0, 0, 0, 0, 0, 0, 0, "IT0", "IE0", "IT1", "IE1", "TR0", "TF0", "TR1", "TF1", "T2", "T2EX", 0, 0, 0, 0, 0, 0, "RI", "TI", "RB8", "TB8", "REN", "SM2", "SM1", "SM0", 0, 0, 0, 0, 0, 0, 0, 0, "EX0", "ET0", "EX1", "ET1", "ES", "ET2", 0, "EA", "RXD", "TXD", "INT0", "INT1", "T0", "T1", "WR", "RD", "PX0", "PT0", "PX1", "PT1", "PS", "PT2", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "CP_RL2", "C_T2", "TR2", "EXEN2", "TCLK", "RCLK", "EXF2", "TF2", "P", 0, "OV", "RS0", "RS1", "F0", "AC", "CY", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,};void PrintBit(byte B) { byte Byte, Bit; if (!Generating) return; if (B < 0x80) { PrintByte(B); return; } B -= 0x80; if (Bits[B] != 0) { printf(Bits[B]); return; } Byte = B&0x78; Bit = B&0x07; if (SFRs[Byte] != 0) { printf("%s.%1x", SFRs[Byte], Bit); return; } PrintByte((byte)(B + 0x80));}void PrintImmByte(byte B) { if (!Generating) return; putchar('#'); PrintByte(B);}void PrintImmWord(word W) { if (!Generating) return; putchar('#'); PrintWord(W);}byte CheckSum; word HighAddr;byte Nib(int X) { if (X >= '0' && X <= '9') return X - '0'; if (X >= 'a' && X <= 'f') return X - 'a' + 10; if (X >= 'A' && X <= 'F') return X - 'A' + 10; fprintf(stderr, "Bad hexadecimal digit in input.\n"); exit(1);}byte GetHex(void) { int A, B; byte Bt; A = getchar(); B = getchar(); if (A == EOF || B == EOF) { fprintf(stderr, "Unexpected EOF.\n"); exit(1); } Bt = Nib(A) << 4 | Nib(B); CheckSum = (CheckSum + Bt)&0xff; return Bt;}word GetWord(void) { word A, B; A = GetHex(); B = GetHex(); return (A << 8) | B;}void HexLoad(void) { int Ch, I; byte Size, Mark, CheckSum; word Addr; byte Buffer[0x10]; HighAddr = 0; while (1) { do { Ch = getchar(); if (Ch == EOF) { fprintf(stderr, "Unexpected EOF.\n"); exit(1); } } while (Ch != ':'); CheckSum = 0; Size = GetHex(); Addr = GetWord(); Mark = GetHex(); for (I = 0; I < Size; I++) Buffer[I] = GetHex(); (void)GetHex(); if (CheckSum != 0) { fprintf(stderr, "Bad checksum.\n"); exit(1); } if (Mark) break; if (Addr >= 0x4000 - Size) { printf("Address out of range 0 - 4000h in input.\n"); exit(0); } for (I = 0; I < Size; I++, Addr++) Hex[Addr] = Buffer[I], Ref[Addr] = 0; if (Addr > HighAddr) HighAddr = Addr; (void)getchar(); }}#define IN_RANGE(A) ((A) >= 0x0000 && (A) < HighAddr)word Address;void PutLabel(word PC) { byte B; if (!Generating) Address = PC; else { if (PC >= 0x4000) { PrintWord(PC); return; } B = (Ref[PC]&LINKS) + 'A'; printf("%c%04x", B, PC); }}void MakeOp(char *S) { int A; byte B; for (A = 1; *S != '\0'; S++) { if (*S != '%') { if (Generating) putchar(*S); continue; } S++; if (*S >= '0' && *S <= '2') A = *S++ - '0'; switch (*S) { case 'L': B = Arg[A++]; PutLabel(B << 8 | Arg[A++]); break; case 'P': PutLabel(Paged(Arg[A++])); break; case 'R': PutLabel(Relative(Arg[A++])); break; case 'D': PrintData(Arg[A++]); break; case 'B': PrintBit(Arg[A++]); break; case 'I': PrintImmByte(Arg[A++]); break; case 'W': B = Arg[A++]; PrintImmWord(B << 8 | Arg[A++]); break; case 'i': if (Generating) printf("@R%1x", Arg[0]&1); break; case 'n': if (Generating) printf("R%1x", Arg[0]&7); break; default: fprintf(stderr, "Bad format string, PC = %04x.\n", PC); exit(1); } } if (Generating) putchar('\n'); else if (!IN_RANGE(Address)) printf("REF: %04x\n", Address); else PUSH(Address);}int Disassemble(void) { byte B; byte Mode; char *Name; int I; if (Ref[PC]&ARG) { fprintf(stderr, "OP into ARG at %04x.\n", PC); return 1; } if (Generating) { if (Ref[PC]&ENTRY) { PutLabel(PC); printf(":\n"); } } else { if (Ref[PC]&OP) return 1; Ref[PC] |= OP; } Arg[0] = B = Hex[PC++]; Mode = Xs[B]; Name = Ns[B]; for (I = 1; I < (Mode&3); I++) { if (Ref[PC]&OP) { fprintf(stderr, "ARG into OP at %04x.\n", PC); return 1; } if (!Generating) { if (Ref[PC]&ARG) { fprintf(stderr, "ARG into ARG at %04x.\n", PC); return 1; } Ref[PC] |= ARG; } Arg[I] = Hex[PC++]; } if (Generating) { if (!(Mode&8)) printf(" "); MakeOp(Name); } else { if (Mode&4) MakeOp(Name); if (Mode&0x10) { printf("Indirect jump at %04x\n", PC - (Mode&3)); } } return (!Generating && (Mode&8) || Generating && !Ref[PC]);}void PCHAR(byte B) { putchar((B < 0x20 || B >= 0x7f)? ' ': B); }int Ended; FILE *EntryF;byte fGetHex(void) { int A, B; if (Ended) return 0; A = fgetc(EntryF); B = fgetc(EntryF); if (A == EOF || B == EOF) { Ended = 1; return 0; } return Nib(A) << 4 | Nib(B);}word fGetWord(void) { word A, B; A = fGetHex(); B = fGetHex(); (void)fgetc(EntryF); if (Ended) return 0; return (A << 8) | B;}void main(void) { word *E, W; HexLoad();fprintf(stderr, "First pass\n"); Generating = 0; EntryF = fopen("entries", "r"); if (EntryF == NULL) { fprintf(stderr, "No entry points listed.\n"); exit(1); } for (Ended = 0, EP = Entries; !Ended; ) { W = fGetWord(); if (!Ended) PUSH(W); } while (EP > Entries) { PC = *--EP; while (!Disassemble()); }fprintf(stderr, "Second pass\n"); Generating = 1; if (Ref[0]) printf("org 0\n"); for (PC = 0x00; IN_RANGE(PC); ) { byte F, Buf[16]; if (!Ref[PC]) { printf("DATA AT "); PrintWord(PC); putchar('\n'); for (F = 0; !Ref[PC] && IN_RANGE(PC); PC++) { Buf[F++] = Hex[PC]; if (F == 16) { for (F = 0; F < 16; F++) { printf("%2x", Buf[F]); if (F < 15) putchar(' '); else putchar('|'); } for (F = 0; F < 16; F++) PCHAR(Buf[F]); putchar('|'); putchar('\n'); F = 0; } } if (F > 0) { byte F1; for (F1 = 0; F1 < F; F1++) printf("%2x ", Buf[F1]); for (; F1 < 16; F1++) { Buf[F1] = 0; printf(" "); if (F1 < 15) putchar(' '); else putchar('|'); } for (F = 0; F < 16; F++) PCHAR(Buf[F]); putchar('|'); putchar('\n'); } if (!IN_RANGE(PC)) break; printf("org "); PrintWord(PC); putchar('\n'); } while (!Disassemble()); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -