📄 sh2d.c
字号:
{
if (strcmp(argv[i], option) == 0) /* found */
{
if (i >= argc) /* bounds! */
return 0;
t[i + 1] = t[i] = 1; /* touched */
if (!h)
return atoi(argv[i + 1]);
else
return strtoul(argv[i + 1], &c, 16);
}
}
return 0; /* no match */
}
else /* find option and return position */
{
for (i = 1; i < argc; i++)
{
if (strcmp(argv[i], option) == 0)
{
t[i] = 1;
return i; /* found! return position */
}
}
return 0;
}
}
/*
* SH2Disasm(): SH-1/SH-2 disassembler routine. If mode = 0 then SH-2 mode,
* otherwise SH-1 mode
*/
void SH2Disasm(unsigned v_addr, unsigned char *p_addr, int mode, char *m_addr)
{
int i;
unsigned short op;
op = (unsigned short) (*p_addr << 8) | *(p_addr + 1);
printf("0x%08X: 0x%04X\t", v_addr, op);
if (m_addr[0]==ND8_F)
{
if (m_addr[2]==-1)
{
unsigned int tmp = (op << 16) | ((unsigned int) (p_addr [2] << 8) | p_addr[3]);
printf(".long\t0x%08X\t; 0x%08X",tmp,v_addr - (unsigned)m_addr[1]);
}
else
printf(".short\t0x%08X\t; 0x%08X",op,v_addr - (unsigned)m_addr[1]);
}
else if (m_addr[0] != -1)
{
for (i = 0; tab[i].mnem != NULL; i++) /* 0 format */
{
if ((op & tab[i].mask) == tab[i].bits)
{
if (tab[i].sh2 && mode) /* if SH-1 mode, no SH-2 */
printf("???");
else if (tab[i].format == ZERO_F)
printf("%s", tab[i].mnem);
else if (tab[i].format == N_F)
printf(tab[i].mnem, (op >> 8) & 0xf);
else if (tab[i].format == M_F)
printf(tab[i].mnem, (op >> 8) & 0xf);
else if (tab[i].format == NM_F)
printf(tab[i].mnem, (op >> 4) & 0xf,
(op >> 8) & 0xf);
else if (tab[i].format == MD_F)
{
if (op & 0x100)
printf(tab[i].mnem, (op & 0xf) * 2,
(op >> 4) & 0xf);
else
printf(tab[i].mnem, op & 0xf,
(op >> 4) & 0xf);
}
else if (tab[i].format == ND4_F)
{
if (op & 0x100)
printf(tab[i].mnem, (op & 0xf) * 2,
(op >> 4) & 0xf);
else
printf(tab[i].mnem, (op & 0xf),
(op >> 4) & 0xf);
}
else if (tab[i].format == NMD_F)
{
if ((op & 0xf000) == 0x1000)
printf(tab[i].mnem, (op >> 4) & 0xf,
(op & 0xf) * 4,
(op >> 8) & 0xf);
else
printf(tab[i].mnem, (op & 0xf) * 4,
(op >> 4) & 0xf,
(op >> 8) & 0xf);
}
else if (tab[i].format == D_F)
{
if (tab[i].dat <= 4)
{
if ((op & 0xff00) == 0xc700)
{
printf(tab[i].mnem,
(op & 0xff) *
tab[i].dat + 4);
printf("\t; 0x%08X",
(op & 0xff) *
tab[i].dat + 4 +
v_addr);
}
else
printf(tab[i].mnem,
(op & 0xff) *
tab[i].dat);
}
else
{
if (op & 0x80) /* sign extend */
printf(tab[i].mnem,
(((op & 0xff) +
0xffffff00) * 2) +
v_addr + 4);
else
printf(tab[i].mnem,
((op & 0xff) * 2) +
v_addr + 4);
}
}
else if (tab[i].format == D12_F)
{
if (op & 0x800) /* sign extend */
printf(tab[i].mnem,
((op & 0xfff) + 0xfffff000) * 2
+ v_addr + 4);
else
printf(tab[i].mnem, (op & 0xfff) * 2 +
v_addr + 4);
}
else if (tab[i].format == ND8_F)
{
int imm = (op & 0xff) * tab[i].dat + 4;
if ((op & 0xf000) == 0x9000) /* .W */
{
int dat = (unsigned short) (*(imm + p_addr) << 8) | *(imm + p_addr + 1);
m_addr[imm+0] = ND8_F; /* this couldn't be an instruction so mark it ! */
m_addr[imm+1] = imm;
printf(tab[i].mnem,
imm,
(op >> 8) & 0xf);
printf("\t; 0x%08X (0x%04X)",
imm + v_addr, dat);
}
else /* .L */
{
unsigned char *b_addr = (unsigned char *)((int)p_addr & 0xfffffffc);
int dat = (unsigned int) (*(imm + b_addr) << 24) | (*(imm + b_addr + 1) << 16)
| (*(imm + b_addr + 2) << 8) | *(imm + b_addr + 3) ;
/* SH-1 register name lookup */
char* str = "";
if ( (dat & 0xfffffe00) == 0x05fffe00 )
str = regname[dat & 0x1ff];
m_addr[imm+(b_addr-p_addr)+0] = ND8_F; /* this couldn't be an instruction so mark it ! */
m_addr[imm+(b_addr-p_addr)+1] = imm;
m_addr[imm+(b_addr-p_addr)+2] = -1;
printf(tab[i].mnem,
imm,
(op >> 8) & 0xf);
printf("\t; 0x%08X (0x%08X) %s",
imm + (v_addr & 0xfffffffc), dat, str);
}
}
else if (tab[i].format == I_F)
printf(tab[i].mnem, op & 0xff);
else if (tab[i].format == NI_F)
printf(tab[i].mnem, op & 0xff, (op >> 8) &
0xf);
else
printf("???");
printf("\n");
return;
}
}
printf("???");
}
printf("\n");
}
void ShowHelp()
{
printf("sh2d Version %s by Bart Trzynadlowski: A Free SH-1/SH-2 "
"Disassembler\n", VERSION);
printf("Usage: sh2d <file> [options]\n");
printf("Options: -?,-h Show this help text\n");
printf(" -s # Start offset (hexadecimal)\n");
printf(" -l # Number of bytes (decimal)\n");
printf(" -o # Set origin (hexadecimal)\n");
printf(" -sh1 SH-1 disassembly only\n");
printf(" -sh2 SH-2 disassembly (default)\n");
exit(0);
}
int main(int argc, char **argv)
{
FILE *fp;
long fsize, file, mode;
unsigned start, len, calc_len = 0, org, do_org, i, j = 0;
char *buffer;
char *mark;
if (argc == 1) /* show help */
ShowHelp();
if (FindOption("-?", 0, 0, 0, argc, argv) ||
FindOption("-h", 0, 0, 0, argc, argv))
ShowHelp();
if (FindOption("-sh1", 0, 0, 0, argc, argv))
mode = 1; /* SH-1 mode */
else
mode = 0; /* SH-2 mode */
if (FindOption("-sh2", 0, 0, 0, argc, argv))
mode = 0; /* SH-2 mode */
start = FindOption("-s", 1, 1, 0, argc, argv);
org = FindOption("-o", 1, 1, 0, argc, argv);
if (!(len = FindOption("-l", 1, 0, 0, argc, argv)))
{
if (FindOption("-l", 0, 0, 0, argc, argv))
return 0; /* -l was actually specified w/ 0 */
calc_len = 1; /* no -l, calculate length */
}
if (FindOption("-o", 0, 0, 0, argc, argv))
do_org = 1; /* -o was actually 0 */
else
do_org = 0; /* there was no -o, ignore the org variable */
if (!(file = FindOption(NULL, 0, 0, 1, argc, argv)))
{
fprintf(stderr, "sh2d: No input file specified. Try "
"\"sh2d -h\" for usage instructions\n");
exit(1);
}
if ((fp = fopen(argv[file], "rb")) == NULL)
{
fprintf(stderr, "sh2d: Failed to open file: %s\n",
argv[file]);
exit(1);
}
fseek(fp, 0, SEEK_END);
fsize = ftell(fp);
rewind(fp);
if ((buffer = (unsigned char *) calloc(fsize * 2, sizeof(unsigned short)))
== NULL)
{
fprintf(stderr, "sh2d: Not enough memory to load input "
"file: %s, %lu bytes\n", argv[file], fsize);
exit(1);
}
fread(buffer, sizeof(unsigned char), fsize, fp);
fclose(fp);
if (calc_len)
len = fsize - start;
mark = buffer + fsize;
for (i = start; i < (unsigned) fsize && j < len; i += 2)
{
if (do_org)
{
SH2Disasm(org, &buffer[i], mode, &mark[i]);
org += 2;
}
else
SH2Disasm(i, &buffer[i], mode, &mark[i]);
j += 2;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -