📄 kernel.x
字号:
regs[1] = ~(*p).y;
regs[2] = ~(*p).z;
int reg;
for (i=0;i<3;i++)
{
reg = regs[i];
if (reg != 0)
{
if (argc <= i)
{
sys_puts("error 338");
return 0xFFFF;
}
else s = argv[i+1];
k = (reg & code);
if (k == reg) // 参数为寄存器编号的情况
{
if (s[0] != 'R' && s[0] != 'r')
{
sys_puts("error 347");
return 0xFFFF;
}
s ++;
}
if ((value = get_value(s,&error)) == 0xFFFF)
return value;
while ((reg & 1) == 0) //参数为寄存器或有符号数的情况
{
if ((value & 0x8000) != 0)
{
sys_puts("error 358");
return 0xFFFF;
}
reg = (reg >> 1);
value = (value << 1);
}
reg = ~regs[i];
if ((reg & value) != 0)
{
sys_puts("error 367");
return 0xFFFF;
}
code = ((code & reg) | value);
}
else if (argc != i+1)
{
sys_puts("error 374");
return 0xFFFF;
}
else break;
}
return code;
}
int parse(char *buffer,char **argv) //从键盘接收一行字符,将其按段(以空格为标志)存入二维数组argv中
{
char ch;
int i, j, argc;
i = 0;
while ((ch = sys_getchar()) != '\n' && i < 31) //从键盘接收字符串,存入buffer中,回车结束,最长31个字符
{
if (ch == 8) // 输入的是back键
{
if (i != 0)
{
i --;
sys_putchar((char)8);
sys_putchar(' ');
sys_putchar((char)8);
}
}
else
{
sys_putchar(ch);
buffer[i++] = ch;
}
}
if (i == 31)
return 0x10; //输入过长
argc = j = 0;
buffer[i] = '\0';
for (i=0;buffer[i] != '\0';i++) //argv中保存的是每个段(以空格分开,实际上就是每个参数的字符串表示),argc记录段数,buffer中的空格变为'\0'
{
if (buffer[i] != ' ')
{
if (j == 0)
{
if (argc == 8)
return 0x20;//分段过多
argv[argc++] = &buffer[i];
}
j = 1;
}
else
{
j = 0;
buffer[i] = '\0';
}
}
return argc;
}
int strcmp(char *s1,char *s2,int choose)
{
if (strlen(s1) != strlen(s2))
return 1;
int i;
for (i=0;*(s1+i)!=0;i++)
{
if (s1[i] != s2[i])
{
if (choose == 1)
{
if ((char)(s1[i]-32) != s2[i] && s1[i] != (char)(s2[i]-32))
return 1;
}
else return 1;
}
}
return 0;
}
void sys_putregs()
{
int i;
for (i=0;i<6;i++)
{
sys_putchar('R');
sys_putchar((char)(i+48));
sys_puts(" = ");
sys_puthex(Reg[i]);
sys_puts(" ");
if (i == 2)
{
sys_putchar('\n');
}
}
sys_putchar('\n');
}
void sys_command()
{
int code;
char [32]buffer;
char *[8]argv;
int argc, addr, var, i, j, k, error;
int t0,t1,t2,t3,t4,t5;
addr = 0x4000;
char ch;
//struct Reg *regs;
while (1)
{
sys_puts(">>");
argc = parse(buffer,argv); //从键盘接收一行字符,将其按段(以空格为标志)存入二维数组argv中
//返回值argc为段数(上限为8)或错误代号(0x10或0x20)
if (argc != 0) //有输入,则往下处理;如用户无输入(直接回车)则再执行while循环,重新等待用户输入
{
if (strlen(argv[0]) == 1) //如果第一段只有一个字符(这应该是除了load命令以外正确的情况)
{
ch = argv[0][0]; //取ch为第一个参数
if (ch <= 'z' && ch >= 'a') //如果是小写字母,转换为大写字母
ch = (char)(ch-32);
if (ch == 'A') //A命令
//(使用A [地址]命令可以从指定地址(缺省为4000地址)开始写入汇编指令。)
{
addr = get_value(argv[1],&error);
if (addr == 0xFFFF || addr >= 0x6000 || addr < 0x4000) addr = 0x4000;
while (argc != 0) //以空串结束指令的输入过程
{
sys_puts(" [");
sys_puthex(addr);
sys_puts("] ");
argc = parse(buffer,argv); //从键盘接收用户输入的汇编指令
if (argc != 0)
{
code = asm(argc,argv); //将MIPS指令转换为二进制编码
if (code != 0xFFFF)
{
*(int *)addr = code; //将二进制指令码写入相应的内存单元中
addr ++; //地址++
}
}
}
*(int *)addr = 0x4e01; //ADDIU R6 1
addr ++; //地址++
*(int *)addr = 0xee00; //JR R6
addr ++; //地址++
*(int *)addr = 0x6700; //MOVE R0 R0
sys_putchar('\n');
}
else if (ch == 'U') //U命令(反汇编)
//(使用U [地址] [指令数目]命令可以从指定地址(缺省为4000地址或
// 上一次U指令结束的地址)开始反汇编指定数量条指令(其缺省值为10)。)
{
addr = get_value(argv[1],&error);
if(addr == 0xFFFF || addr>=0x6000 || addr<0x4000) addr = 0x4000;
if (argc <= 2 || (var = get_value(argv[2],&error)) < 10) //省略第三个参数或第三个参数小于10
var = 10;
for (i=0;i<var;i++)
{
sys_puts(" [");
sys_puthex(addr);
sys_puts("] ");
uasm(*(int *)addr); //反汇编
addr ++;
}
}
else if (ch == 'D') //D命令(查看内存数据)
//(使用D [地址] [指令数目]命令可以查看指定地址(缺省为4000地址或
// 上一次U指令结束的地址)的数据(其缺省值为10)。)
{
addr = get_value(argv[1],&error);
if(addr == 0xFFFF || addr>=0x6000 || addr<0x4000) addr = 0x4000;
if (argc <= 2 || (var = get_value(argv[2],&error)) < 10) //省略第三个参数或第三个参数小于10
var = 10;
for (i=0;i<var;i++)
{
sys_puts(" [");
sys_puthex(addr);
sys_puts("] ");
sys_puthex(*(int *)addr);
sys_putchar('\n');
addr ++;
}
}
else if (ch == 'E') //E命令(写入内存数据)
//(使用E <地址> <数据>命令可以将数据写入指定地址。)
{
addr = get_value(argv[1],&error);
if(addr <0x6000 && addr>=0x4000){ //在正常的可访问地址范围内
if (argc = 3){ //存在第三个参数
var = get_value(argv[2],&error);
*(int *)addr = var;
}
}
}
else if (ch == 'G') //G命令
//(使用G[地址]命令运行指定的指令。)
{
addr = get_value(argv[1],&error);
if(addr == 0xFFFF || addr>=0x6000 || addr<0x4000) addr = 0x4000;
t0 = Reg[0];
t1 = Reg[1];
t2 = Reg[2];
t3 = Reg[3];
t4 = Reg[4];
t5 = Reg[5];
%asm{
%writereg("r1", t1);
%writereg("r2", t2);
%writereg("r3", t3);
%writereg("r4", t4);
%writereg("r5", t5);
%writereg("r0", addr);
%asm("MFPC", "r6");
%asm("JR", "r0");
%asm("MOVE", "r0", "r0");
%readreg("r0", t0);
%readreg("r1", t1);
%readreg("r2", t2);
%readreg("r3", t3);
%readreg("r4", t4);
%readreg("r5", t5);
};
Reg[0] = t0;
Reg[1] = t1;
Reg[2] = t2;
Reg[3] = t3;
Reg[4] = t4;
Reg[5] = t5;
sys_putregs();
}
else if (ch == 'R') //R命令
//(使用R指令可以查看当前所有环境中所有寄存器的值。)
{
sys_putregs();
}
}
}
}
}
int main ()
{
//串口初始化
*(int *)0x6001 = 0x4E;
*(int *)0x6001 = 0x37;
*(int *)0x6003 = 0x4E;
*(int *)0x6003 = 0x37;
//显示欢迎界面,并要求用户设置debug_mode
sys_puts("Welcome to Xaser kernel 0.5.0 [2008/5/22] designed for mips16e CPU.\n");
init();
sys_command();
while (1);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -