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

📄 disass.c

📁 AT91所有开发板的资料 AT91所有开发板的资料
💻 C
📖 第 1 页 / 共 3 页
字号:
}#ifndef NO_MALLOCvoid disass_addcopro(Disass_CoProProc *f) {    CoProRec *p = copros;    for (; p != NULL; p = p->next)        if (p->f == f)            return;    p = (CoProRec *)malloc(sizeof(CoProRec));    p->next = copros; p->f = f;    copros = p;}#endif#ifndef NO_MALLOCvoid disass_deletecopro(Disass_CoProProc *f) {    CoProRec **pp = &copros, *p;    for (; (p = *pp) != NULL; pp = &p->next)        if (p->f == f) {            *pp = p->next;            free(p);            return;        }}#endifstatic char *DPOp2(unsigned32 instr, unsigned32 address, char *o) {    if (bit(25)) {            /* rhs is immediate */      int op = (int)bits(21,24);      int shift = 2*(int)bits(8,11);      int32 operand = ror(bits(0,7), shift);      char *oldo = o;      if ((op == 4 || op == 2) && /* ADD or SUB  */          bits(16,19) == 15 &&        /* rn = pc */          cb_proc != NULL)        o = cb_proc((op == 4 ? D_ADDPCREL : D_SUBPCREL),                    operand, address+8, 0, cb_arg, o);      if (o == oldo) {          o = outh(operand, 1, o);          if ((op == 4 || op == 2) && /* ADD or SUB */              bits(16,19) == 15) {       /* rn = pc */              o = Dis_OutS(" ; ", o);              o = outh(address+8 + ((op == 4) ? operand : -operand),                       1, o);          }      }    }    else {                   /* rhs is a register */      o = shiftedreg(instr, o);    }    return o;}unsigned32 disass_32or26(unsigned32 instr, unsigned32 address, char *o, void *cba, dis_cb *cbp, int mode_32bit) {    char notes[64];    notes[0] = 0;    cb_proc = cbp; cb_arg = cba;    switch (bits(24,27)) {    case 0:       if (bits(4,7) == 9) {         /* Arithmetic extension space */         if (bits(22,23) == 0) {           o = Dis_ArmOpCode(instr, (bit(21) ? "MLA" : "MUL"), (bit(20) ? 'S' : 0), o);           o = Dis_ArmReg(bits(16,19), ',', o);           o = Dis_ArmReg(bits(0,3), ',', o);           o = Dis_ArmReg(bits(8,11), 0, o);           if (bit(21)) {             o = Dis_OutC(',', o);             o = Dis_ArmReg(bits(12,15), 0, o);           }           break;         } else if (bit(23)==1) {           /* Long Multiply */           o=Dis_ArmOpCode(instr, bit(21) ? (bit(22) ? "SMLAL" : "UMLAL")                                       : (bit(22) ? "SMULL" : "UMULL"),                        bit(20) ? 'S' : 0, o);           o = Dis_ArmReg(bits(12,15), ',', o);           o = Dis_ArmReg(bits(16,19), ',', o);           o = Dis_ArmReg(bits(0,3), ',', o);           o = Dis_ArmReg(bits(8,11), 0, o);           break;         } else {           Dis_AddNote(notes, "Bad arithmetic extension op = %ld", bits(20,23));           /* And fall through to disassemble as data-processing */         }       }       /* Drop through */    case 1: case 2: case 3:       if (bits(26,27) == 0 && bits(23,24) == 2 && !bit(20) &&           (bit(25) || !bit(7) || !bit(4))) {         /* Control extension space */         if (!bit(25) && bits(4,7) == 1 && bits(8,19) == 0xfff &&             bits(21,22) == 1) {           o = Dis_ArmOpCode(instr, "BX", 0, o);           o = Dis_ArmReg(bits(0, 3), 0, o);           break;         }         if (!bit(25) && bits(4,7) == 3 && bits(8,19) == 0xfff &&             bits(21,22) == 1) {           o = Dis_ArmOpCode(instr, "BLX", 0, o);           o = Dis_ArmReg(bits(0, 3), 0, o);           break;         }         if ((bits(20,27) == 0x16) && bits(4,7) == 1){           o = Dis_ArmOpCode(instr, "CLZ", 0, o);           o = Dis_ArmReg(bits(12, 15), ',', o);           o = Dis_ArmReg(bits(0, 3), 0, o);           break;         }         if (bits(4,11) == 0x05 && bits(23,27) == 2 && !bit(20)) {           /* El Segundo saturated arithmetic */           char *satname = NULL;           bool swap_sources = FALSE;           unsigned32 src1, src2;           switch(bits(21,22)) {           case 0: satname = "QADD";                       break;           case 1: satname = "QSUB";                       break;           case 2: satname = "QDADD"; swap_sources = TRUE; break;           case 3: satname = "QDSUB"; swap_sources = TRUE; break;           }           o = Dis_ArmOpCode(instr, satname, 0, o);           o = Dis_ArmReg(bits(12, 15), ',', o);           src1 = bits(16, 19);           src2 = bits(0, 3);           if (swap_sources)           {               unsigned32 tmpsrc = src1; src1 = src2; src2 = tmpsrc;           }           o = Dis_ArmReg(src1, ',', o);           o = Dis_ArmReg(src2, 0, o);           break;         }         if (bits(23, 27) == 2 && !bit(20) && !bit(4) && bit(7)) {           /* El Segundo narrow multiply instructions */           char *mname = NULL;           enum { fourth_reg_none,                  fourth_reg_is_rn,                  fourth_reg_is_rdlo                } fourth_reg = fourth_reg_none;           char mulname[10];           bool select_rm = TRUE;           switch(bits(21,22)) {           case 0:             mname = "SMLA";             fourth_reg = fourth_reg_is_rn;             break;           case 1:             select_rm = FALSE;             if (bit(5)) {               mname = "SMULW";             } else {               mname = "SMLAW";               fourth_reg = fourth_reg_is_rn;             }             break;           case 2:             mname = "SMLAL";             fourth_reg = fourth_reg_is_rdlo;             break;           case 3:             mname = "SMUL";             break;           }           strcpy(mulname, mname);           if (select_rm)             strcat(mulname, bit(5) ? "T" : "B");           strcat(mulname, bit(6) ? "T" : "B");           o = Dis_ArmOpCode(instr, mulname, 0, o);           if (fourth_reg == fourth_reg_is_rdlo)             o = Dis_ArmReg(bits(12, 15), ',', o);           o = Dis_ArmReg(bits(16, 19), ',', o);           o = Dis_ArmReg(bits(0, 3), ',', o);           o = Dis_ArmReg(bits(8, 11), ","[fourth_reg != fourth_reg_is_rn], o);           if (fourth_reg == fourth_reg_is_rn)             o = Dis_ArmReg(bits(12, 15), 0, o);           break;         }         if (!bit(25) && !bit(21)) {           o = Dis_ArmOpCode(instr, "MRS", 0, o);           o = Dis_ArmReg(bits(12,15), ',', o);           o = Dis_OutS(!bit(22) ? "CPSR" : "SPSR", o);           Dis_CheckZero(bits(0,11), "0-11", notes);           Dis_CheckValue(bits(16,19), 15, "Rn", notes);           break;         }         if (bit(21)) {           const char *rname = !bit(22) ? "CPSR" : "SPSR";           int rn = (int)bits(16, 19);           char flags[8];           char *f = flags;           *f++ = '_';           if (rn & 1) *f++ = 'c';           if (rn & 2) *f++ = 'x';           if (rn & 4) *f++ = 's';           if (rn & 8) *f++ = 'f';           if (rn == 0) Dis_AddNote(notes, "field-mask = 0");           *f++ = ',';           *f = '\0';           o = Dis_ArmOpCode(instr, "MSR", 0, o);           o = Dis_OutS(rname, o);           o = Dis_OutS(flags, o);           Dis_CheckValue(bits(12,15), 15, "Rd", notes);           if (!bit(25))             Dis_CheckZero(bits(4,11), "4-11", notes);           o = DPOp2(instr, address, o);           break;         }         Dis_AddNote(notes, "Bad control extension op");       }       if (bits(25,27) == 0 && bit(7) && bit(4)           && (bit(24) || bits(5,6))) {         /* Load-store extension space */         if (bits(23,24) == 2 && bits(20,21) == 0 && bits(4,11) == 9) {           /* Swap */           o = Dis_ArmOpCode(instr, "SWP", (bit(22) ? 'B' : 0), o);           o = Dis_ArmReg(bits(12,15), ',', o);           o = Dis_ArmReg(bits(0,3), ',', o);           o = Dis_OutC('[', o); o = Dis_ArmReg(bits(16,19), ']', o);           break;         }          if (bit(20) ? bits(5,6) != 0 : bits(5,6) == 1) {           char *start = o;           o = Dis_OutS(bit(20) ? "LDR" : "STR", o);           o = Dis_cond(instr, o);           if (bit(6)) {             o = Dis_OutC('S', o);             o = Dis_OutC(bit(5) ? 'H' : 'B', o);           } else             o = Dis_OutC('H', o);           o = Dis_spacetocol9(start, o);           o = Dis_ArmReg(bits(12,15), ',', o);           o = Dis_OutC('[', o);           o = Dis_ArmReg(bits(16,19), 0, o);           if (bit(24)) o = Dis_OutC(',', o); else o = Dis_OutC(']', o), o = Dis_OutC(',', o);           if (bit(22)) {             o = outh(bits(0, 3) + (bits(8,11)<<4), bit(23), o);           } else {             if (!bit(23)) o = Dis_OutC('-',o);             o = Dis_ArmReg(bits(0,3),0,o);           }           if (bit(24)) {             o = Dis_OutC(']', o);             if (bit(21)) o = Dis_OutC('!', o);           } else if (bit(21))             Dis_AddNote(notes, "Post-indexed, W=1");           break;         }         Dis_AddNote(notes, "Bad load/store extension op");       }       if (instr == 0xe1a00000L) {          o = Dis_ArmOpCode(instr, "NOP", 0, o);          break;       }       { /* data processing */          int op = (int)bits(21,24);          const char *opnames = "AND\0EOR\0SUB\0RSB\0ADD\0ADC\0SBC\0RSC\0\TST\0TEQ\0CMP\0CMN\0ORR\0MOV\0BIC\0MVN";          unsigned32 rd = bits(12,15);          int ch = (!bit(20)) ? 0 :             (op>=8 && op<12) ? (rd==15 ? 'P' : 0) :                                 'S';          o = Dis_ArmOpCode(instr, opnames+4*op, ch, o);          if (op >= 8 && op < 12) {    /* TST TEQ CMP CMN */            if (rd != 15)              Dis_CheckZero(rd, "Rd", notes);           } else {             /* print the dest reg */             o = Dis_ArmReg(rd, ',', o);          }          if (op == 13 || op == 15) {         /* MOV MVN */            Dis_CheckZero(bits(16,19), "Rn", notes);          } else {            o = Dis_ArmReg(bits(16,19), ',', o);          }          o = DPOp2(instr, address, o);       }       break;    case 0xa: case 0xb:       if (bits(25,31) == 0x7d) {          char *start = o ;          o = Dis_OutS("BLX", o);          o = Dis_spacetocol9(start, o);          }       else          o = Dis_ArmOpCode(instr, (bit(24) ? "BL" : "B"), 0, o);       {  int32 offset = (((int32)bits(0,23))<<8)>>6; /* sign extend and * 4 */          char *oldo = o;          if (bits(24,31) == 0xfb)             offset |= bit(24) >> 23 ;          address += offset + 8;          if (!mode_32bit) address &= 0x3ffffffL;          if (cb_proc != NULL)             o = cb_proc(D_BORBL, offset, address, 0, cb_arg, o);          if (o == oldo) o = Dis_OutX(address, o);       }       break;    case 6: case 7:       /* Cope with the case where register shift register is specified        * as this is an undefined instruction rather than an LDR or STR        */         if (bit(4)) {           o=Dis_OutS("Undefined Instruction",o);           break;         }       /* Drop through to alwasy LDR / STR case */    case 4: case 5:       {  char *start = o;          o = Dis_OutS(bit(20) ? "LDR" : "STR", o);          o = Dis_cond(instr, o);          if (bit(22)) o = Dis_OutC('B', o);          if (!bit(24) && bit(21))  /* post, writeback */             o = Dis_OutC('T', o);          o = Dis_spacetocol9(start, o);          o = Dis_ArmReg(bits(12,15), ',', o);          o = Dis_ArmOutAddress(instr, address, bits(0,11), (bit(22) ? 1 : 4), o);          break;       }    case 8: case 9:       {  char *start = o;          o = Dis_OutS(bit(20) ? "LDM" : "STM", o);          o = Dis_cond(instr, o);          o = Dis_OutS("DA\0\0IA\0\0DB\0\0IB" + 4*(int)bits(23,24), o);          o = Dis_spacetocol9(start, o);          o = Dis_ArmReg(bits(16,19), 0, o);          if (bit(21)) o = Dis_OutC('!', o);          o = Dis_OutC(',', o);          o = outregset(instr, o);          if (bit(22)) o = Dis_OutC('^', o);          break;       }    case 0xf:       o = Dis_ArmOpCode(instr, "SWI", 0, o);       {  char *oldo = o;          int32 swino = bits(0,23);          if (cb_proc != NULL)             o = cb_proc(D_SWI, swino, 0, 0, cb_arg, o);          if (o == oldo) o = Dis_OutX(swino, o);       }       break;    case 0xe:       o = HandleCoPro(bit(4)==0 ? CP_DP : CP_RT, instr, address, o, notes);       break;    case 0xc: case 0xd:       o = HandleCoPro(CP_DT, instr, address, o, notes);       break;    default:       o = Dis_OutS("EQUD    ", o);       o = Dis_OutX(instr, o);    }    if (notes[0] != 0) o = Dis_OutF(o, " ; ? %s", notes);    o = Dis_OutC('\0', o);    return 4;}

⌨️ 快捷键说明

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