⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kernel.x

📁 一个用自己写的编译器编译的操作系统内核. 有包含中断和不包含中断两个版本. 还有简单的用户应用程序。 因为该代码原目的是下载到硬件上使用
💻 X
📖 第 1 页 / 共 2 页
字号:
	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 + -