1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/cryt-asm_to_logisim_rom

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
asm.c 6 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
yalewoo Отправлено 03.01.2015 10:37 b69e5d2
/*
* 在线代码托管:http://git.oschina.net/cryt/asm_to_logisim_rom
*/
#include "header.h"
char optable[OP_NUM]; //存储一个命令对应的二进制机器码 读文件symbol-op.txt后确定
int main(int argc, char *argv[])
{
char command[COMMAND_MAX_LEN]; //存放一行命令的缓冲区
FILE *fasm; //打开源文件指针
FILE *fbin; //生成目标文件指针
int counter = 0; //用来控制输出按照logisim格式 8个数据一行
int line = 0; //记录当前处理的是源代码中的哪一行
int label_pos = 0; //记录当前处理的是源代码有效语句的第几行(用于将标号转换为具体的位置数字)
int error = 0;
int error_happen = 0;
struct label label[LABEL_NUM];
int label_n = 0;
readOpFile();
if (argc == 2)
{
if ((fasm = fopen(argv[1], "r")) == NULL)
{
fprintf(stderr, "open %s failed\n", argv[1]);
exit(-1);
}
}
else
{
if ((fasm = fopen("src.asm", "r")) == NULL)
{
fprintf(stderr, "open src.asm failed\n");
exit(-1);
}
}
if ((fbin = fopen("rom.txt", "w")) == NULL)
{
fprintf(stderr, "open %s failed\n", argv[1]);
exit(-1);
}
fprintf(fbin, "v2.0 raw\n"); //logisim中rom导入数据的格式
//生成标号和行号对应关系
while (!feof(fasm))
{
fgets(command, COMMAND_MAX_LEN, fasm);
command[strlen(command)] = '\n';
if (createLabelTable(label, &label_n, command, label_pos) == 1)
{
++label_pos;
}
}
//回到文件起始部分
fseek(fasm, 0, SEEK_SET);
//循环读取源代码 每次一行 直到文件尾
counter = 0;
while (!feof(fasm))
{
error = 0;
fgets(command, COMMAND_MAX_LEN, fasm);
if (command[strlen(command) - 1] != '\n')
{
command[strlen(command)] = '\n';
command[strlen(command)+1] = '\0';
}
++line;
if (asmToHex(label, label_n, command, fbin, &error) == 1)
{
++counter;
if (counter == 8)
{
counter = 0;
fprintf(fbin, "\n");
}
else
fprintf(fbin, " ");
}
else
{
if (error)
{
error_happen = 1;
printError(command, error, line);
}
}
}
fclose(fasm);
fclose(fbin);
if (error_happen)
{
printf("Press Enter to Exit\n");
getchar();
}
return 0;
}
//空行返回0 有效语句返回1
int asmToHex(struct label *label, int label_n, char *command, FILE *fp, int *error)
{
int i = 0;
int j;
int k;
int len;
char *pnum;
long addr;
enum symbol_type status;
//忽略前导空白符
while (command[i] == ' ' || command[i] == '\t')
{
++i;
}
//判断是否是空行 (包括只有注释)
if (command[i] == '\n' || command[i] == ';')
return 0;
j = i;
while (command[j] != ':' && command[j] != '\n')
++j;
if (command[j] == ':')
{
i = j+1;
while (command[i] == ' ' || command[i] == '\t')
{
++i;
}
if (command[i] == '\n')
return 0;
}
status = whatType(command+i, &len);
i += len;
++i; //现在i指向ADD [123]的'[ 或jmp 12的'1' 或 JZ s1的's'处
if (command[i] == '[')
++i;
//处理jmp 标号 这种情况
if ((status == JMP || status == JO || status == JZ) && (command[i] < '0' || command[i] > '9'))
{
for (j = i; command[j] != ' ' && command[j] != '\n' && command[j] != '\t' && command[j] != ';'; ++j)
;
for (k = 0; k < label_n; ++k)
{
if (strncmp(command+i, label[k].label, j-i) == 0 && label[k].label[j-i] == '\0')
{
fprintf(fp, "%c%03X", optable[status], label[k].pos);
return 1;
}
}
*error = 1;
return 0;
}
//把文本形式的 123H 1010B 79转换为int类型保存在addr
strtol(command+i, &pnum, 16);
if (*pnum == 'H' || *pnum == 'h')
addr = strtol(command+i, &pnum, 16);
else if (*(pnum-1) == 'b' || *(pnum-1) == 'B')
addr = strtol(command+i, &pnum, 2);
else
addr = strtol(command+i, &pnum, 10);
fprintf(fp, "%c%03X", optable[status], (unsigned int)addr);
return 1;
}
//空行返回0 有效语句返回1
int createLabelTable(struct label *label, int *label_n, char *command, int label_pos)
{
int i = 0;
int j;
//忽略前导空白符
while (command[i] == ' ' || command[i] == '\t')
{
++i;
}
//判断是否是空行 (包括只有注释)
if (command[i] == '\n' || command[i] == ';')
return 0;
j = i;
while (command[j] != ':' && command[j] != '\n')
++j;
if (command[j] == ':')
{
label[*label_n].pos = label_pos;
strncpy(label[*label_n].label, command + i, j-i);
label[*label_n].label[j-i] = '\0';
++(*label_n);
}
if (command[j] == '\n')
return 1;
++j;
while (command[j] == ' ' || command[j] == '\t')
{
++j;
}
if (command[j] == '\n')
return 0;
else
return 1;
}
void readOpFile(void)
{
FILE *fsymbol_op;
int i;
char op[2];
char *pnum;
long num;
char command[COMMAND_MAX_LEN]; //存放一行命令的缓冲区
enum symbol_type status;
if ((fsymbol_op = fopen("symbol-op.txt", "r")) == NULL)
{
fprintf(stderr, "open symbol-op.txt failed\n");
exit(-1);
}
while (!feof(fsymbol_op))
{
fgets(command, COMMAND_MAX_LEN, fsymbol_op);
command[strlen(command)] = '\n';
i = 0;
if (command[i] == '#')
continue;
status = whatType(command, &i);
num = strtol(command+i, &pnum, 2);
sprintf(op, "%1X", (unsigned int)num);
optable[status] = *op;
}
}
//返回伪代码类型 begin指向伪指令 len返回指令长度
enum symbol_type whatType(char *begin, int *len)
{
enum symbol_type status;
int i = 0;
switch (begin[0])
{
case 'n':
case 'N':
status = NOP;
i = 3;
break;
case 'l':
case 'L':
status = LOAD;
i = 4;
break;
case 'x':
case 'X':
status = XOR;
i = 3;
break;
case 'o':
case 'O':
status = OR;
i = 2;
break;
case 'a':
case 'A':
status = ADD;
i = 3;
break;
case 's':
case 'S':
if (begin[1] == 'u' || begin[1] == 'U')
{
status = SUB;
i = 3;
break;
}
else
{
status = STORE;
i = 5;
break;
}
case 'j':
case 'J':
if (begin[1] == 'm' || begin[1] == 'M')
{
status = JMP;
i = 3;
break;
}
else if (begin[1] == 'o' || begin[1] == 'O')
{
status = JO;
i = 2;
break;
}
else
{
status = JZ;
i = 2;
break;
}
case 'e':
case 'E':
status = EXIT;
i = 4;
break;
default:
break;
}
*len = i;
return status;
}
void printError(char *command, int error, int line)
{
int i;
switch (error)
{
case 1:
printf("第%d行错误:不认识的标号:\n", line);
for (i = 0; command[i] != '\n'; ++i)
putchar(command[i]);
printf("\n");
break;
default:
break;
}
}

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/cryt-asm_to_logisim_rom.git
git@api.gitlife.ru:oschina-mirror/cryt-asm_to_logisim_rom.git
oschina-mirror
cryt-asm_to_logisim_rom
cryt-asm_to_logisim_rom
master