📄 unasmarmdlg.cpp
字号:
int offset;
char str[128], temp[128];
int TooBad = 0;
if ( (src_buffer[i] & 8) == 0)
{
if ( (src_buffer[i+2] & 0xf8) != 0xf8)
TooBad = 1;
}
else
TooBad = 1;
if (TooBad)
{
i_delta = 2;
do_dis_thumb (fd_src, fd_tar, cur_addr,
addr, 19,
(unsigned char) src_buffer[i],
(unsigned char) src_buffer[i+1]);
cur_addr += 2;
continue;
}
offset = (src_buffer[i+3] & 0xff) |
( (src_buffer[i+2] & 7) << 8) |
( (src_buffer[i+1] & 0xff) << 11) |
( (src_buffer[i] & 7) << 19);
if (offset & 0x200000)
{
( (unsigned char *) &offset) [3] = 0xff;
( (unsigned char *) &offset) [2] |= 0xc0;
}
offset = cur_addr + (offset << 1) + 4;
if (m_Hex)
{
sprintf (str, "%08x %02X%02X%02X%02X ",
cur_addr, 0xff & src_buffer[i],
0xff & src_buffer[i+1],
0xff & src_buffer[i+2],
0xff & src_buffer[i+3]);
}
else
{
sprintf (str, "%08x ", cur_addr);
}
sprintf (temp, "BL 0x%08x\n", offset);
regNo = -1;
strcat (str, temp);
fwrite (str, 1, strlen (str), fd_tar);
cur_addr += 4;
}
}
}
if (i_delta == 2)
remains = 0;
}
}
if (CrLf)
CrLf = 0;
else
fwrite ("\n", 1, 1, fd_tar);
return 0;
}
int CUnasmARMDlg::dis_thumb_one (unsigned char * bin_code)
{
unsigned uch;
int op_type; //1-19
uch = bin_code[0] & 0xf0; // 1111 0000
switch (uch)
{
case 0x00:
op_type = 1; // Move shifted register
break;
case 0x10:
if ( (bin_code[0] & 0xf8) == 0x18)
op_type = 2; // Add/substract
else
op_type = 1; // Move shifted register
break;
case 0x20:
case 0x30:
op_type = 3; // Move/compare/add/substract imm
break;
case 0x40:
if ( (bin_code[0] & 0xfc) == 0x40)
{
op_type = 4; // ALU operations
break;
}
if ( (bin_code[0] & 0xfc) == 0x44)
{
op_type = 5; // Hi register operation/Branch exchange
break;
}
op_type = 6; // PC-relative load
break;
case 0x50:
if ( (bin_code[0] & 0xf2) == 0x52)
op_type = 8; // Load/store sign-exted byte/hw
else
op_type = 7; // Load/store with register offset
break;
case 0x60:
case 0x70:
op_type = 9; // Load/store with imm offset
break;
case 0x80:
op_type = 10; // Load/store halfword
break;
case 0x90:
op_type = 11; // SP-relative load/store
break;
case 0xa0:
op_type = 12; // Load address
break;
case 0xb0:
if (bin_code[0] == 0xb0)
op_type = 13; // Add offset to stack pointer
else
op_type = 14; // Push/pop registers
break;
case 0xc0:
op_type = 15; // Multiple load/store
break;
case 0xd0:
if (bin_code[0] == 0xdf)
op_type = 17; // Software interrupt
else
op_type = 16; // Conditional branch
break;
case 0xe0:
op_type = 18; // Unconditional branch
break;
case 0xf0:
op_type = 19; // Long branch with link
break;
}
return op_type;
}
int CUnasmARMDlg::do_dis_thumb (FILE * fd_src, FILE * fd_tar,
long addr, long start, int op_type,
unsigned char byte1, unsigned char byte2)
{
char fourbytes[4], str[128];
unsigned long tar_addr;
char temp[128];
int op, Rd, Rs, Rn, Ro, Rb, offset5, Cond, LB, HS;
char *op_name = {"MOV CMP ADD SUB "};
char *op_name1 = {"AND EOR LSL LSR ASR ADC SBC ROR TST NEG CMP CMN ORR MUL BIC MVN "};
char *op_name2 = {"LSL LSR ASR "};
char *cond_name = {"BEQ BNE BCS BCC BMI BPL BVS BVC BHI BLS BGE BLT BGT BLE "};
char *op_name3 = {"STR STRBLDR LDRB"};
char *op_name4 = {"STRHLDSBLDRHLDSH"};
char *op_name5 = {"STR LDR STRBLDRB"};
char *op_name6 = {"ADD CMP MOV BX "};
long cur_loc;
int len;
CrLf = 0;
if (m_Hex)
{
sprintf (str, "%08x %02X%02X ", addr, byte1, byte2);
}
else
{
sprintf (str, "%08x ", addr);
}
switch (op_type)
{
case 1:
op = (byte1 & 0x18) >> 3;
memcpy (temp, &op_name2[op << 2], 4);
temp[4] = '\0';
strcat (temp, " ");
offset5 = ( (byte1 & 7) << 2) | ( (byte2 & 0xc0) >> 6);
if (op)
{
if (offset5 == 0)
offset5 = 32;
}
Rd = byte2 & 7;
Rs = (byte2 & 0x38) >> 3;
if (Rd != Rs)
{
sprintf (&temp[8], "R%d, R%d, #%d", Rd, Rs, offset5);
if ( (Rs == regNo) && (!op) )
{
len = strlen (temp);
if (offset5 < 10)
sprintf (&temp[len], " ;%08x", regValue << offset5);
else
sprintf (&temp[len], " ;%08x", regValue << offset5);
}
}
else
{
sprintf (&temp[8], "R%d, #%d", Rd, offset5);
if ( (Rs == regNo) && (!op) )
{
len = strlen (temp);
if (offset5 < 10)
sprintf (&temp[len], " ;%08x", regValue << offset5);
else
sprintf (&temp[len], " ;%08x", regValue << offset5);
}
}
regNo = -1;
strcat (str, temp);
break;
case 2:
Rn = ( (byte1 & 1) << 2) | ( (byte2 & 0xc0) >> 6);
Rd = byte2 & 7;
Rs = (byte2 & 0x38) >> 3;
if (byte1 & 2)
strcpy (temp, "SUB ");
else
strcpy (temp, "ADD ");
if (byte1 & 4)
{ // Immediate operation
if (Rn == 0)
{
temp[0] = 'M'; // ADD rd, rs, #0 -> MOV rd, rs
temp[1] = 'O';
temp[2] = 'V';
sprintf (&temp[8], "R%d, R%d", Rd, Rs);
}
else
{
sprintf (&temp[8], "R%d, R%d, #%d", Rd, Rs, Rn);
}
}
else
{ // Register operation
sprintf (&temp[8], "R%d, R%d, R%d",
Rd, Rs, Rn);
}
regNo = -1;
strcat (str, temp);
break;
case 3:
op = (byte1 & 0x18) >> 3;
memcpy (temp, &op_name[op << 3], 8);
Rd = byte1 & 7;
if ( (Rd == 15) && (op == 0) )
CrLf = 1;
if (byte2 > 9)
sprintf (&temp[8], "%s, #0x%02x", RegisterName[Rd], byte2);
else
sprintf (&temp[8], "%s, #%d", RegisterName[Rd], byte2);
if (!op)
{
regNo = Rd;
regValue = byte2;
}
if (op == 2)
{
if (Rd == regNo)
{
len = strlen (temp);
if (byte2 > 9)
sprintf (&temp[len], " ;%08x", regValue + byte2);
else
sprintf (&temp[len], " ;%08x", regValue + byte2);
regNo = -1;
}
}
strcat (str, temp);
break;
case 4:
op = ( (byte1 & 3) << 2) | ( (byte2 & 0xc0) ) >> 6;
memcpy (temp, &op_name1[op << 2], 4);
temp[4] = '\0';
strcat (temp, " ");
Rd = byte2 & 7;
Rs = (byte2 & 0x38) >> 3;
sprintf (&temp[8], "R%d, R%d", Rd, Rs);
regNo = -1;
strcat (str, temp);
break;
case 5:
op = byte1 & 3;
memcpy (temp, &op_name6[op << 2], 4);
temp[4] = '\0';
strcat (temp, " ");
if (op == 3)
{ // BX
Rs = (byte2 & 0x38) >> 3;
HS = ( (byte2 & 0xc0) >> 6) & 3;
if (HS == 1)
Rs += 8;
sprintf (temp, "BX %s", RegisterName[Rs]);
CrLf = 1;
}
else
{
Rs = (byte2 & 0x38) >> 3;
Rd = byte2 & 7;
HS = ( (byte2 & 0xc0) >> 6) & 3;
if (HS == 0)
{
strcat (temp, "??????");
}
else
{
if (HS == 1)
Rs += 8;
if (HS == 2)
Rd += 8;
if (HS == 3)
{
Rs += 8;
Rd += 8;
}
if ( (Rd == 15) && (op == 2) ) // MOV PC, ...
CrLf = 1;
sprintf (&temp[8], "%s, %s", RegisterName[Rd], RegisterName[Rs]);
}
}
strcat (str, temp);
regNo = -1;
break;
case 6:
float f;
Rd = byte1 & 7;
tar_addr = ( (byte2 << 2) + addr + 4) & 0xfffffffc;
cur_loc = ftell (fd_src);
fseek (fd_src, tar_addr - start, SEEK_SET);
fread ( fourbytes, 1, 4, fd_src);
fseek (fd_src, cur_loc, SEEK_SET);
if (Rd < 10)
{
if ( (unsigned) fourbytes[0] >= '0')
{
if (m_Radio1)
{
( (char *) (&f) ) [0] = fourbytes[3];
( (char *) (&f) ) [1] = fourbytes[2];
( (char *) (&f) ) [2] = fourbytes[1];
( (char *) (&f) ) [3] = fourbytes[0];
sprintf (temp, "LDR R%d, 0x%08x ;%02x%02x%02x%02x(%g)",
Rd, tar_addr, 0xff & fourbytes[0],
0xff & fourbytes[1], 0xff & fourbytes[2],
0xff & fourbytes[3], f);
}
else
{
( (char *) (&f) ) [0] = fourbytes[0];
( (char *) (&f) ) [1] = fourbytes[1];
( (char *) (&f) ) [2] = fourbytes[2];
( (char *) (&f) ) [3] = fourbytes[3];
sprintf (temp, "LDR R%d, 0x%08x ;%02x%02x%02x%02x(%g)",
Rd, tar_addr, 0xff & fourbytes[3],
0xff & fourbytes[2], 0xff & fourbytes[1],
0xff & fourbytes[0], f);
}
}
else
{
if (m_Radio1)
{
sprintf (temp, "LDR R%d, 0x%08x ;%02x%02x%02x%02x",
Rd, tar_addr, 0xff & fourbytes[0],
0xff & fourbytes[1], 0xff & fourbytes[2],
0xff & fourbytes[3]);
}
else
{
sprintf (temp, "LDR R%d, 0x%08x ;%02x%02x%02x%02x",
Rd, tar_addr, 0xff & fourbytes[3],
0xff & fourbytes[2], 0xff & fourbytes[1],
0xff & fourbytes[0]);
}
}
}
else
{
if ( (unsigned) fourbytes[0] >= '0')
{
if (m_Radio1)
{
( (char *) (&f) ) [0] = fourbytes[3];
( (char *) (&f) ) [1] = fourbytes[2];
( (char *) (&f) ) [2] = fourbytes[1];
( (char *) (&f) ) [3] = fourbytes[0];
sprintf (temp, "LDR R%d, 0x%08x ;%02x%02x%02x%02x(%g)",
Rd, tar_addr, 0xff & fourbytes[0],
0xff & fourbytes[1], 0xff & fourbytes[2],
0xff & fourbytes[3], f);
}
else
{
( (char *) (&f) ) [0] = fourbytes[0];
( (char *) (&f) ) [1] = fourbytes[1];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -