配套CPU指令集
追加寄存器,扩展指令集,分离经纬控制线与数据线中途,意外重整CPU,并发现设备控制端口与指令一行8个数字调试更方便_哔哩哔哩_bilibili
#include <stdio.h>
#include <windows.h>
#include <string.h>
// 寄存器对应机器位
int sign_regist(char* chose) {
if (strcmp(chose, "AX") == 0) {
return 1; // 寄存器
} else if (strcmp(chose, "BX") == 0) {
return 2;
} else if (strcmp(chose, "CX") == 0) {
return 3;
} else if (strcmp(chose, "DX") == 0) {
return 4;
} else if (strcmp(chose, "EX") == 0) {
return 5;
} else if (strcmp(chose, "FX") == 0) {
return 6;
} else if (strcmp(chose, "GX") == 0) {
return 7;
} else {
return -1; // 发现错误字符
}
}
char trans_16(int a) {
if (a >= 0 && a <= 9) {
return '0' + a;
} else {
return 'a' + a - 10;
}
}
// 接收命令行参数
int main(int args, char **argv) {
printf("第一次测试数据翻译,启动\n");
printf("在windows下运行命令:start ccy.exe\n");
// poweshell 下运行
printf("命令格式:./ccy.exe gdd 目标文件名.txt -o 生成文件名.txt\n");
//打印看不到就写入文件里
FILE* fp;
fp = fopen(argv[3], "w");
FILE* src;
src = fopen(argv[1], "r");
char order[30];
for (int i = 0; i < 30; i++) {
order[i] = '\0';
}
int n; // 当前字符,用于检测空格
int cnt; // 当前存储词序号用于commend数组
int num; // 当前存储词的字母所在数组序号用于commend数组
int have; // 当前机器指令序号用于bin数组
int line = 0; // 记录读取行数,在-1返回检测提示
char commend[3][10]; // 分割词语,最多3个 a + b 给到 c, 每个词语最多10个字符 ADD AX BX CX
int bin[255][8]; // 十六进制命令一共8个十六进制数,支持255行指令
char bintext[255][8]; // 输出文本十六进制a b c d e f 替换10 11 12 13 14 15
// 清除未知残留数据
for (int i = 0; i < 255; i++) {
for (int j = 0; j < 8; j++) {
bin[i][j] = 0;
}
}
// 还得是追加清除数据
// 读取回车,所以文本最后要自己加回车,否则最后数据读不到
while (fgets(order, 30, src) != 0) {
line++;
// 手动分割命令,利用空格筛选数据
n = 0;
cnt = 0;
num = 0;
while (1) {
// 按空格分割词
// 先查是否结束
if (order[n] == '\0') {
commend[cnt][num] = '\0';
num = 0;
break;
} else if (order[n] == ' ') {
commend[cnt][num] = '\0'; // 追加结束符用于后续字符转数字
num = 0;
cnt++;
// 由于回车读取后变成'\0'所以直接比较新数据
} else {
commend[cnt][num] = order[n];
// printf("%c\n", order[n]);
num++;
}
n++;
}
// printf("cccnnt=%d\n",cnt);
// 对号入座
// 寄存器加载数据
// LOAD AX xxx, xxx是数据
if (strcmp(commend[0], "LOAD") == 0) {
// 字符转数字
int k = 0;
int test = 0;
int all[10];
int sum = 0;
// 逆序数据追加
while (commend[2][test] != '\0') {
// printf("%c\n", commend[2][test]);
all[test] = commend[2][test] - '0';
test++; // 突然发现test没增加
}
// printf("%d\n", test);
// 最大的序号对应最高位
// for (int i = test - 2; i >= 0; i--) {
// 发现按位记录,就顺序
for (int i = 0; i < test - 1 ; i++) {
printf("%d\n", all[i]);
// 发现是先乘10再加各位
sum *= 10;
sum += all[i];
}
printf("加载数据立即数sum= %d\n", sum);
// 对应1000 第二组控制线路,允许接收数据
bin[have][0] = 0;
bin[have][1] = 0; // 其实这一位啥都行,电路里没有冲突,这里先整一个追加寄存器
bin[have][2] = 0;
bin[have][3] = 0;
// bin[have][4] = 0; // 寄存器
int sign = sign_regist(commend[1]);
if (sign == -1) {
printf("寄存器指定错误,第 %d 行", line);
}
bin[have][4] = sign_regist(commend[1]); // 寄存器
bin[have][5] = 0;
// 发现要转成16进制
// 高位,但是存左侧低地址
bin[have][6] = sum % 16;
bin[have][7] = sum / 16;
// 比如 ff07000 是给第七个寄存器写入ff 就是 15*16+15= 255
}
// 寄存器数据相加
// ADD AX BX (CX)第三位可选
else if (strcmp(commend[0], "ADD") == 0) {
} else {
printf("没有发现匹配命令 %d\n", line);
}
have++;
// 清空本行存储
for (int i = 0; i < 30; i++) {
order[i] = '\0';
}
}
// 补充翻译写入文本
for (int i = 0; i < have; i++) {
for (int j = 0; j < 8; j++) {
// printf("%-2d ", bin[i][7 - j]);
// fprintf(fp, "%-2d ", bin[i][7 - j]);
bintext[i][j] = trans_16(bin[i][7 - j]);
printf("%c", bintext[i][j]);
fprintf(fp, "%c", bintext[i][j]);
}
printf("\n");
fprintf(fp, "\n");
}
fclose(fp);
fclose(src);
return 0;
}