📄 dis_arm_instr.c
字号:
case 'F':
switch (given & 0x00408000) {
case 0:
printf( "4");
break;
case 0x8000:
printf( "1");
break;
case 0x00400000:
printf( "2");
break;
default:
printf( "3");
}
break;
case 'P':
switch (given & 0x00080080) {
case 0:
printf( "s");
break;
case 0x80:
printf( "d");
break;
case 0x00080000:
printf( "e");
break;
default:
printf( "<illegal precision>");
break;
}
break;
case 'Q':
switch (given & 0x00408000) {
case 0:
printf( "s");
break;
case 0x8000:
printf( "d");
break;
case 0x00400000:
printf( "e");
break;
default:
printf( "p");
break;
}
break;
case 'R':
switch (given & 0x60) {
case 0:
break;
case 0x20:
printf( "p");
break;
case 0x40:
printf( "m");
break;
default:
printf( "z");
break;
}
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{
int bitstart = *c++ - '0';
int bitend = 0;
while (*c >= '0' && *c <= '9')
bitstart = (bitstart * 10) + *c++ - '0';
switch (*c) {
case '-':
c++;
while (*c >= '0' && *c <= '9')
bitend = (bitend * 10) + *c++ - '0';
if (!bitend) {
printf( "***OOPS!***");
return 4;
}
switch (*c) {
case 'r':
{
long reg;
reg = given >> bitstart;
reg &= (2 << (bitend - bitstart)) - 1;
printf( "%s", arm_regnames[reg]);
}
break;
case 'd':
{
long reg;
reg = given >> bitstart;
reg &= (2 << (bitend - bitstart)) - 1;
printf( "%ld", reg);
}
break;
case 'x':
{
long reg;
reg = given >> bitstart;
reg &= (2 << (bitend - bitstart)) - 1;
printf( "0x%08lx", reg);
/* Some SWI instructions have special
meanings. */
if ((given & 0x0fffffff) == 0x0FF00000)
printf( " ; IMB");
else if ((given & 0x0fffffff) == 0x0FF00001)
printf( " ; IMBRange");
}
break;
case 'X':
{
long reg;
reg = given >> bitstart;
reg &= (2 << (bitend - bitstart)) - 1;
printf( "%01lx", reg & 0xf);
}
break;
case 'f':
{
long reg;
reg = given >> bitstart;
reg &= (2 << (bitend - bitstart)) - 1;
if (reg > 7)
printf( "#%s",
arm_fp_const[reg & 7]);
else
printf( "f%ld", reg);
}
break;
default:
printf( "***OOPS!***");
return 4;
}
break;
case '`':
c++;
if ((given & (1 << bitstart)) == 0)
printf( "%c", *c);
break;
case '\'':
c++;
if ((given & (1 << bitstart)) != 0)
printf( "%c", *c);
break;
case '?':
++c;
if ((given & (1 << bitstart)) != 0)
printf( "%c", *c++);
else
printf( "%c", *++c);
break;
default:
printf( "***OOPS!***");
return 4;
}
break;
default:
printf( "***OOPS!***");
return 4;
}
}
#ifdef NOTABS
} else if (*c == '\t') {
printf( "%c", ' ');
#endif
} else {
printf( "%c", *c);
}
}
return 4;
}
}
printf( "***OOPS!***");
return 4;
}
/*************************************************************************/
int
disarm_print_thumb_instr (unsigned long pc, long given)
{
struct thumb_opcode * insn;
for (insn = thumb_opcodes; insn->assembler; insn++) {
if ((given & insn->mask) == insn->value) {
char * c = insn->assembler;
/* Special processing for Thumb 2 instruction BL sequence: */
if (!*c) { /* Check for empty (not NULL) assembler string. */
printf( "bl\t");
#if 0
info->print_address_func (BDISP23 (given) * 2 + pc + 4, info);
#else
printf( "0x%lx", BDISP23 (given) * 2 + pc + 4);
#endif
return 4;
} else {
given &= 0xffff;
for (; *c; c++) {
if (*c == '%') {
int domaskpc = 0;
int domasklr = 0;
switch (*++c) {
case '%':
printf( "%%");
break;
case 'S':
{
long reg;
reg = (given >> 3) & 0x7;
if (given & (1 << 6))
reg += 8;
printf( "%s", arm_regnames[reg]);
}
break;
case 'D':
{
long reg;
reg = given & 0x7;
if (given & (1 << 7))
reg += 8;
printf( "%s", arm_regnames[reg]);
}
break;
case 'T':
printf( "%s",
arm_conditional [(given >> 8) & 0xf]);
break;
case 'N':
if (given & (1 << 8))
domasklr = 1;
/* Fall through. */
case 'O':
if (*c == 'O' && (given & (1 << 8)))
domaskpc = 1;
/* Fall through. */
case 'M':
{
int started = 0;
int reg;
printf( "{");
/* It would be nice if we could spot
ranges, and generate the rS-rE format: */
for (reg = 0; (reg < 8); reg++)
if ((given & (1 << reg)) != 0) {
if (started)
printf( ", ");
started = 1;
printf( "%s", arm_regnames[reg]);
}
if (domasklr) {
if (started)
printf( ", ");
started = 1;
printf( (char *)arm_regnames[14] /* "lr" */);
}
if (domaskpc) {
if (started)
printf( ", ");
printf( (char *)arm_regnames[15] /* "pc" */);
}
printf( "}");
}
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{
int bitstart = *c++ - '0';
int bitend = 0;
while (*c >= '0' && *c <= '9')
bitstart = (bitstart * 10) + *c++ - '0';
switch (*c) {
case '-':
{
long reg;
c++;
while (*c >= '0' && *c <= '9')
bitend = (bitend * 10) + *c++ - '0';
if (!bitend) {
printf( "***OOPS!***");
return 2;
}
reg = given >> bitstart;
reg &= (2 << (bitend - bitstart)) - 1;
switch (*c) {
case 'r':
printf( "%s", arm_regnames[reg]);
break;
case 'd':
printf( "%ld", reg);
break;
case 'H':
printf( "%ld", reg << 1);
break;
case 'W':
printf( "%ld", reg << 2);
break;
case 'a':
/* PC-relative address -- the bottom two
bits of the address are dropped
before the calculation. */
#if 0
info->print_address_func
(((pc + 4) & ~3) + (reg << 2), info);
#else
printf( "0x%lx",
((pc + 4) & ~3) + (reg << 2));
#endif
break;
case 'x':
printf( "0x%04lx", reg);
break;
case 'I':
reg = ((reg ^ (1 << bitend))
- (1 << bitend));
printf( "%ld", reg);
break;
case 'B':
reg = ((reg ^ (1 << bitend))
- (1 << bitend));
#if 0
(*info->print_address_func)
(reg * 2 + pc + 4, info);
#else
printf( "0x%lx", reg * 2 + pc + 4);
#endif
break;
default:
printf( "***OOPS!***");
return 2;
}
}
break;
case '\'':
c++;
if ((given & (1 << bitstart)) != 0)
printf( "%c", *c);
break;
case '?':
++c;
if ((given & (1 << bitstart)) != 0)
printf( "%c", *c++);
else
printf( "%c", *++c);
break;
default:
printf( "***OOPS!***");
return 2;
}
}
break;
default:
printf( "***OOPS!***");
return 2;
}
#ifdef NOTABS
} else if (*c == '\t') {
printf( "%c", ' ');
#endif
} else
printf( "%c", *c);
}
}
return 2;
}
}
/* No match. */
printf( "***OOPS!***");
return 2;
}
/*************************************************************************/
#endif /* of INCLUDE_DISASSEMBLER */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -