📄 analyze52.c
字号:
start = i;
j = TRUE;
}
}
}
return FALSE;
}
// Check if data at 'pc' appears to be an ascii string.
// Return TRUE if so, else return FALSE.
bool isString(int pc, int stop)
{
int i;
bool retval = FALSE;
byte data;
data = pgmmem[pc];
if (isprint(data) && data != '"')
{
for (i=0; i<MIN_STR_LEN && pc<stop; i++)
{
data = pgmmem[pc++];
if (!isprint(data) || data == '"')
break;
}
if (i >= MIN_STR_LEN) // if at least min ascii chars in
retval = TRUE; // a row, then might be ascii text
}
return retval;
}
// Return address of end of string at 'pc'.
// Assumes that pc does point to a string.
int getEndOfString(int pc, int stop)
{
byte data;
data = pgmmem[pc];
while (isprint(data) && data != '"' && pc < stop)
{
pc++;
data = pgmmem[pc];
}
return pc;
}
// Check if code at 'pc' appears to be traceable.
// Return TRUE if so, else return FALSE.
// We assume it's not valid code if it's a series
// of TRACE_CHECK_LEN bytes of 0x00 or 0xff in a row.
bool isTraceableCode(int pc)
{
int i;
bool retval = FALSE;
byte code;
for (i=0; i<TRACE_CHECK_LEN; i++)
{
code = pgmmem[pc++];
if (code != 0x00 && code != 0xff)
{
retval = TRUE;
break;
}
}
return retval;
}
// Trace a single thread of code starting at address 'pc'.
// Return TRUE if error, else return FALSE.
bool trace(int pc)
{
bool done;
byte code, flag;
int adrs, dest, dptr;
int pushLevelSave = 0;
if (!isTraceableCode(pc)) // does not appear to be executable code,
return FALSE; // but this is not an error
tpc = pc;
astackPtr = 0;
pushLevel = 0;
dptr = 0;
done = FALSE;
while (!done)
{
flag = analysisFlags[tpc];
while (flag & ANALYZE_TAGGED) // if we've already been here,
{
if (astackPtr) // check for addresses on stack
{
--astackPtr;
tpc = astack[astackPtr];
flag = analysisFlags[tpc];
}
else // if stack is empty, we're done
{
done = TRUE;
break;
}
}
if (done)
return FALSE;
code = pgmmem[tpc];
analysisFlags[tpc] = ANALYZE_TAGGED;
switch (code)
{
case OPCODE_LJMP:
tpc++;
analysisFlags[tpc] = ANALYZE_TAGGED;
adrs = pgmmem[tpc++] << 8;
analysisFlags[tpc] = ANALYZE_TAGGED;
adrs |= (pgmmem[tpc] & 0xff);
adrs &= WORD_MASK;
tpc = adrs;
break;
case OPCODE_JBC:
case OPCODE_JB:
case OPCODE_JNB:
adrs = tpc + 3;
tpc++;
analysisFlags[tpc] = ANALYZE_TAGGED;
tpc++;
analysisFlags[tpc] = ANALYZE_TAGGED;
dest = (int) pgmmem[tpc++] & 0xff;
if (dest & 0x80)
dest |= 0xff00;
adrs += dest;
adrs &= WORD_MASK;
astack[astackPtr++] = adrs;
if (astackPtr >= STACK_DEPTH)
{
analysisError("trace stack overflow!");
return TRUE;
}
break;
case OPCODE_LCALL:
pushLevelSave = pushLevel;
pushLevel = 0;
tpc++;
analysisFlags[tpc] = ANALYZE_TAGGED;
adrs = pgmmem[tpc++] << 8;
analysisFlags[tpc] = ANALYZE_TAGGED;
adrs |= (pgmmem[tpc++] & 0xff);
adrs &= WORD_MASK;
astack[astackPtr++] = tpc;
if (astackPtr >= STACK_DEPTH)
{
analysisError("trace stack overflow!");
return TRUE;
}
tpc = adrs;
break;
case OPCODE_RET:
if (pushLevel > 0)
{
pushLevel = pushLevelSave;
vstack[vstackPtr++] = dptr;
if (vstackPtr >= STACK_DEPTH)
{
analysisError("vector stack overflow");
return TRUE;
}
}
case OPCODE_RETI:
case OPCODE_JMP: // jmp @a+dptr - we don't know where this will go
if (astackPtr)
{
--astackPtr;
tpc = astack[astackPtr];
}
else
done = TRUE;
break;
case OPCODE_JC:
case OPCODE_JNC:
case OPCODE_JZ:
case OPCODE_JNZ:
adrs = tpc + 2;
tpc++;
analysisFlags[tpc] = ANALYZE_TAGGED;
dest = (int) pgmmem[tpc++] & 0xff;
if (dest & 0x80)
dest |= 0xff00;
adrs += dest;
adrs &= WORD_MASK;
astack[astackPtr++] = adrs;
if (astackPtr >= STACK_DEPTH)
{
analysisError("trace stack overflow!");
return TRUE;
}
break;
case OPCODE_SJMP:
adrs = tpc + 2;
tpc++;
analysisFlags[tpc] = ANALYZE_TAGGED;
dest = (int) pgmmem[tpc++] & 0xff;
if (dest & 0x80)
dest |= 0xff00;
adrs += dest;
adrs &= WORD_MASK;
tpc = adrs;
break;
case OPCODE_PUSH:
tpc++;
analysisFlags[tpc] = ANALYZE_TAGGED;
tpc++;
pushLevel++;
break;
case OPCODE_POP:
tpc++;
analysisFlags[tpc] = ANALYZE_TAGGED;
tpc++;
if (pushLevel > 0)
--pushLevel;
break;
case OPCODE_MOVDPTR:
tpc++;
analysisFlags[tpc] = ANALYZE_TAGGED;
dptr = pgmmem[tpc++] << 8;
analysisFlags[tpc] = ANALYZE_TAGGED;
dptr |= (pgmmem[tpc++] & 0xff);
dptr &= WORD_MASK;
dstack[dstackPtr++] = dptr;
if (dstackPtr >= STACK_DEPTH)
{
analysisError("dptr stack overflow!");
return TRUE;
}
break;
default:
if ((code & OPCODE_AJMP_MASK) == OPCODE_AJMP)
{
tpc++;
analysisFlags[tpc] = ANALYZE_TAGGED;
adrs = tpc + 1;
dest = ((int) code & 0xe0) << 3;
dest += ((int) pgmmem[tpc++] & 0xff);
dest &= WORD_MASK;
adrs = dest;
tpc = adrs;
}
else if ((code & OPCODE_ACALL_MASK) == OPCODE_ACALL)
{
pushLevelSave = pushLevel;
pushLevel = 0;
tpc++;
analysisFlags[tpc] = ANALYZE_TAGGED;
adrs = tpc + 1;
dest = ((int) code & 0xe0) << 3;
dest |= ((int) pgmmem[tpc++] & 0xff);
dest &= WORD_MASK;
adrs = dest;
astack[astackPtr++] = tpc;
if (astackPtr >= STACK_DEPTH)
{
analysisError("trace stack overflow!");
return TRUE;
}
tpc = adrs;
}
else if ((code == OPCODE_DJNZ1) || (code >= OPCODE_CJNE1 && code <= OPCODE_CJNE2))
{
tpc++;
analysisFlags[tpc] = ANALYZE_TAGGED;
tpc++;
analysisFlags[tpc] = ANALYZE_TAGGED;
adrs = tpc + 1;
dest = (int) pgmmem[tpc++] & 0xff;
if (dest & 0x80)
dest |= 0xff00;
adrs += dest;
adrs &= WORD_MASK;
astack[astackPtr++] = tpc;
if (astackPtr >= STACK_DEPTH)
{
analysisError("trace stack overflow!");
return TRUE;
}
tpc = adrs;
}
else if ((code & OPCODE_DJNZ_MASK) == OPCODE_DJNZ)
{
tpc++;
analysisFlags[tpc] = ANALYZE_TAGGED;
adrs = tpc + 1;
dest = (int) pgmmem[tpc++] & 0xff;
if (dest & 0x80)
dest |= 0xff00;
adrs += dest;
adrs &= WORD_MASK;
astack[astackPtr++] = tpc;
if (astackPtr >= STACK_DEPTH)
{
analysisError("trace stack overflow!");
return TRUE;
}
tpc = adrs;
}
else
{
if (opttbl[code] & OPT_2)
{
tpc++;
analysisFlags[tpc] = ANALYZE_TAGGED;
tpc++;
}
else if (opttbl[code] & OPT_3)
{
tpc++;
analysisFlags[tpc] = ANALYZE_TAGGED;
tpc++;
analysisFlags[tpc] = ANALYZE_TAGGED;
tpc++;
}
else
tpc++;
}
break;
}
}
return FALSE;
}
// Generate list to be written to control file.
// Scan through the program and add list entries
// for each data type (code, ascii, etc).
void genAnalysisList(void)
{
int i;
int start, stop;
byte aflag, lastflag;
char code, ostr[64], datatype[32];
aflag = lastflag = analysisFlags[0];
start = 0;
for (i=0; i<himark; i++)
{
aflag = analysisFlags[i];
if (aflag != lastflag)
{
stop = i - 1;
datatype[0] = '\0';
switch (lastflag & ~ANALYZE_TRACED)
{
case ANALYZE_NONE:
code = 'i';
sprintf(datatype, "\t; Invalid data");
break;
case ANALYZE_CODE:
code = 'c';
sprintf(datatype, "\t; Code space");
break;
case ANALYZE_VECTOR:
code = 'a';
sprintf(datatype, "\t; pointers");
break;
case ANALYZE_BINARY:
code = 'b';
sprintf(datatype, "\t; 8-bit data");
break;
case ANALYZE_ASCII:
code = 't';
sprintf(datatype, "\t; ASCII text");
break;
default:
code = '?';
break;
}
sprintf(ostr, "%c %04x-%04x", code, start, stop);
strcat(ostr, datatype);
addListEntry(ostr);
start = i;
lastflag = aflag;
}
}
}
int createLineList(void)
{
int year;
time_t tp;
if (ctlLineList)
deleteLineList();
ctlLineList = malloc(sizeof(STRLIST));
if (!ctlLineList)
{
printf("No memory for line list.\n");
if (ctlfp)
{
fclose(ctlfp);
ctlfp = NULL;
}
return -1;
}
ctlLineList->str = NULL;
ctlLineList->prev = NULL;
ctlLineList->next = NULL;
addListEntry(";");
strcpy(tempString, "; D52 configuration file for ");
strcat(tempString, src);
addListEntry(tempString);
sprintf(tempString, "; Generated by D52 V%d.%d.%d on ", VERSION, MAJORREV, MINORREV);
time(&tp); // get current time
date_time = localtime(&tp); // convert to hr/min/day etc
year = date_time->tm_year;
while (year > 100)
year -= 100;
sprintf(dateString, "%02d/%02d/%02d %d:%02d", date_time->tm_mon + 1,
date_time->tm_mday, year,
date_time->tm_hour, date_time->tm_min);
strcat(tempString, dateString);
addListEntry(tempString);
addListEntry(";");
return listCount;
}
void deleteLineList(void)
{
STRLIST *list, *prev;
list = ctlLineList;
while (list)
{
prev = list;
list = list->next;
free(prev->str);
free(prev);
}
ctlLineList = NULL;
listCount = 0;
}
int writeCtlFile(void)
{
STRLIST *list;
char *str = NULL;
list = ctlLineList;
if (!list)
{
if (ctlfp)
{
fclose(ctlfp);
ctlfp = NULL;
}
return -1;
}
if (ctlfp)
{
fclose(ctlfp);
strcpy(fileName, ctl);
strcat(fileName, ".backup");
rename(ctl, fileName);
}
ctlfp = fopen(ctl, "w"); // reopen ctl file for writing
if (!ctlfp)
return -1;
while (list)
{
str = list->str;
if (str && *str)
fprintf(ctlfp, "%s\n", str);
list = list->next;
}
fflush(ctlfp);
fclose(ctlfp);
ctlfp = NULL;
return 0;
}
bool addListEntry(char *str)
{
STRLIST *list = ctlLineList;
if (!list)
return FALSE;
while (list->next)
list = list->next;
list->next = malloc(sizeof(STRLIST));
if (!list->next)
return FALSE;
list->next->prev = list;
list = list->next;
list->next = NULL;
list->str = malloc(strlen(str) + 2);
if (!list->str)
return FALSE;
strcpy(list->str, str);
listCount++;
return TRUE;
}
void analysisError(char *msg)
{
sprintf(alertMessage, "\nAnalysis Error - ");
strcat(alertMessage, msg);
printf("%s\n", alertMessage);
}
// end of analyze52.c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -