【开坑】在mc里搞个操作系统!!!!!

大家下午好唷!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
上午考虑了一下io设备接口与shell程序的设计。
但是其中真正关键的部分是调用解释器interpreter。
解释器被设计为能够识别以一个ascii字符串表示的指令。
也就是说,它把一个字符串映射为[操作码][参数]的格式。
然后shell可以直接根据操作码作为调用入口,调用对应的执行器。
一般来说这个问题可以通过散列表hash比较好地解决。
但是这里是mc,即使是散列表的效率也惨不忍睹,
所以还得考虑外接一个专门的译码器decoder,以提高译码效率。
如果在上面处理输入流的方案中,选择了硬接的方案2.
那么这个译码器decoder可以直接配合shell显示器下面的硬件
进行处理:shell显示器模块直接将输入流转译为[操作码][参数]格式.






楼主 savenseg  发布于 2019-05-03 15:37:00 +0800 CST  


楼主 savenseg  发布于 2019-05-03 19:00:00 +0800 CST  
所以总结了下,还是把字符串分析的模块合并到shell显示器模块里了。
cpu和外设的关系变了。如下图

楼主 savenseg  发布于 2019-05-03 19:19:00 +0800 CST  
这样子设计以后,就省去了效率低下的字符串分析程序,转而由硬件实现。
但是也因此,指令的分析被固定了,但是无妨。因为本就不打算更换操作系统。
可以说这个操作系统有一部分被焊到bios里了。不过,我们还可以为命令重定向,
以及增加指令,前者通过设置执行器实现,后者则需要直接拓展decoder,可以手动添加,
也可以在以后再添加一组abi,可以在机器上实现拓展。
字符串被转码后,会将参数和操作码压入InRegA。操作系统可以检测InRegA的状态信号位。
来实现接受命令。另外我们也提供了inregb,以直接捕捉键盘的任何输入。

楼主 savenseg  发布于 2019-05-03 19:26:00 +0800 CST  
接下来。就得考虑下shell的指令了。
目前有打算的是这些:

~rd address:显示[address]的内容
~wr address data:会将data写入单元[address]。
~clr:清屏
~run address:将控制转移到[address]
~lau film_name:启动程序"film_name"
~lnk address film_name:将film_name文件入口重定向为[address]
start会给shell返回一个启动成功/失败的信息,成功的话控制转交给程序。
没有加~的话按enter会直接换行,而不被识别为指令。
只有简单的几个指令,也许还会加一些好玩的命令。
这里不得不提一下这个操作系统的文件系统:
实际上在指令start中的"film_name"只能是个char对象,也就是说他只能是一个字符。
这么做还是为了妥协:降低程序的启动延迟。
这个操作系统会维护一个table关联文件编号。每个不同的film_name都对应一个地址,
cpu获得到film_name后,给film_name的值(会被表示为二进制值)加上一个固定的偏移量c,得到装有文件film_name的起始指针p的地址"c+film_name",start指令会直接根据指针p跳转到这个入口,控制转交程序。程序同样也可以利用这个文件系统。当然,因为简化不会提供关于文件的任何更多信息,所以程序员还需自重。
调试功能可能会由硬件的控制台实现。

楼主 savenseg  发布于 2019-05-03 19:50:00 +0800 CST  
不过。。。为了方便decoder的设计,可能会要求shell指令中的参数前面由0补齐,并且要求参数为16进制。

楼主 savenseg  发布于 2019-05-03 19:51:00 +0800 CST  
总的下来有关shell显示器模块还有shell的讨论已经差不多了。
然后需要考虑的是点阵屏display。
肯定不能让他直接打点。。不然就太慢了。
display的abi大概可以提供这几个功能:
画点draw.point(x,y)
画线draw.line(x,y,dir,len)//被阉割成九十度方向限定的了
打印字符print(x,y,n)
字符打印是个问题。预计会让这些字符规范为4*4的像素符号。当然5*5也说不定。
然后可以在任意位置打印在显示器上。
这些字符的形状又得通过一块存储器提供了。也许它会是一个已经编辑好的rom,
也可能会提供编辑这些字符形状的接口。

楼主 savenseg  发布于 2019-05-03 20:25:00 +0800 CST  
总结下现在的工作吧!

__display的操作:
draw.point
draw.line
print

display提供的接口:【A】【B】【C】【D】【E】【F】六个连续的地址单元,前四个传入参数,E发送操作码为信号,F接受返回值

__shell显示器:

shell显示器接受处理keyboard的输入流。处理后结果递给InRegA,
KeyBoard的输入也被InRegB捕获。

InRegA结构:【sign】【opcode】【data】
InRegB结构:【sign】【data】
InRegA中:sign是bool值,opcode表示要执行的操作,data是传入参数。
InRegB中:sign是bool值,data是键盘最后一个操作的ascii码

cpu提供两个指令:
wait.A
wait.B
分别会等待直到InReg的sign变为1.用于同步通讯A与B.

shell显示器也提供一组接口给cpu程序:
shell.lock()禁止shell显示器捕捉keyboard的输入流
shell.unlock()允许shell显示器捕捉keyboard的输入流
shell.clearline()清空输入行
shell.clear()Shell清屏
shell.print(n)给shell输入一个字符,如果是backspace或者enter会同样执行特殊符效果。

shell显示器的接口结构:
【A】【B】【C】A传参,B发送操作码为信号,C返回值。

还有shell的指令,重新调整了下统一形式
~red
~wrt
~clr
~run
~lau
~lnk

文件名关联表基址:C
文件入口获得方式:寻址[C+film_name]

程序结束时必须跳转回shell程序。

楼主 savenseg  发布于 2019-05-03 20:46:00 +0800 CST  
然后再总结下操作系统给内存安排的结构
[0x00]
[shell程序]
[ABI接口]
[文件关联数组]
[文件]
还是比较简单的,mc的弱鸡内存也放得下。

楼主 savenseg  发布于 2019-05-03 20:54:00 +0800 CST  
讨论玩操作系统和外部设备以后,接下来的任务就是处理器架构设计了

楼主 savenseg  发布于 2019-05-03 20:55:00 +0800 CST  
考虑到大部分程序并不需要高位宽,所以处理器的宽度不需要太大。
全部程序体积不大可能超过几千个单元。综合考虑。处理器宽度可能是8bit或者16bit。
处理器需要面临大量分支处理,这方面必然需要优化。
深思熟虑以后,认为这个cpu有几个方向可以选择:
8bit
16bit
兼容8bit的16bit。

第一种需要分段寻址,但是存储体利用率高
第二种方便一些,但是存储体利用率低了
第三种介于两者之间

楼主 savenseg  发布于 2019-05-03 21:04:00 +0800 CST  
然后就是关于处理器的功能了。
首先这个计算机显然并不需要内核态(因为压根用不到。。。。。)
所以应该不需要加入权级别管理,这么做的缺点是任何程序都可以作为内核。
但是在非常简单的运行环境下无妨。也利用这一点。所有程序都可以得知这么一个前提:
导入内存时即已知所有内存区域的使用情况以及意义。
于是我们规定:
0x00开始是shell程序
shell程序后面是设备接口区
设备接口后面是文件关联数组区
再后面是由操作员任意发挥的空间了(文件区)
所以将采用直接物理地址寻址。程序员需要预先记住内存区域的划分。
在低效率的运行环境下这些牺牲是必要的。


楼主 savenseg  发布于 2019-05-03 22:00:00 +0800 CST  
然后得考虑程序的偏好,shell程序中的大部分工作已经被加速硬件解决了,
他只需要接受inrega里的数据并且根据opcode执行系统调用就ok了。
这些所谓的系统调用被安排在shell程序区,因为它并不会被shell以外的程序调用,当然,
如果想也可以,因为根本没用访问限制。
opcode也可以被提前直接转为系统调用入口地址,因为switch语句还是涉及不少访存,所以顺便就此简化了。当然,可能又有必要让opcode映射变成可编程的,当然这个日后再说

楼主 savenseg  发布于 2019-05-03 22:11:00 +0800 CST  
所以大概shell程序被简化成这样了。。。。

inrega.data -> r1
inreg.opcode -> ip //如果不用专门的jmp实现跳转的话,opcode需要预先-1。并不是大问题。

两行搞定非常方便。基本失去了指令集设计的参考价值

楼主 savenseg  发布于 2019-05-03 22:15:00 +0800 CST  
居然把我的贴吞了。。yamero!!!

考虑到程序例程,可能就是一些简单的棋牌游戏。
以后或许得添加网络接口实现联机。

这些程序应该都有这些特点:
大部分时间都在等待
涉及大量条件分支
数据结构搜索
所以应该和之前考虑的一样:
需要针对条件分式与相对访存优化

楼主 savenseg  发布于 2019-05-03 22:37:00 +0800 CST  
晚安~





楼主 savenseg  发布于 2019-05-03 23:50:00 +0800 CST  
啊啊对了,还得通过寄存器方式寻址,这样才能实现入口跳转,
目前来看有一个比较直接的办法就是通过mov ip,reg=(address-1)实现这个效果,
也可以提供专门指令jmp_reg.就不需要-1了。当然对于这种压根就不理程序计数器溢出异常的
处理器,实际上-1唯一的弊端也可以解决:如果要跳转到0x00,直接输入地址11111111就ok了
因为会自动上溢至00000000.直接挪到ip里面的好处就是如果出现调用返回的话,
就不需要事先对准断点入口了
然后还有个**的问题就是立即数。
立即数肯定得拼凑出来,当然也可以在内存中预先提供立即数,
这样的区别是一个是两个指令格,一个是一个数据格一个内存格。
而且立即数指令有时候只需要读取低位作为立即数,可能只需要一个立即数指令。
并且立即数指令完整的立即数读取会是连续的,而且中间也不会插有额外的访存。
这几点上来看,还是比内存中准备立即数的办法要好一些的


楼主 savenseg  发布于 2019-05-04 00:00:00 +0800 CST  
今天又是美好的一天!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!虽然快乐的时光总是短暂(假期要结束了)

楼主 savenseg  发布于 2019-05-04 09:06:00 +0800 CST  
之前考虑的排序好像代码写错了。。。不管了。
实际上经过思考后我认为提供两个stack会让算法运行更佳高效。
实际上在x86isa中也提供了类似效果的串比较指令,当然就是直接对内存操作了。
所以干脆重新考虑下吧,算法变成这样了:
预先提供这些指令和数据结构:
两个堆栈a,b
可以直接访问堆栈离出口最近的元素(分别通过寄存器名字$a,$b访问)
pop.a rd,pop.b rd,push.a rs,push.b rs是堆栈-寄存器操作指令,
也可以将寄存器中的值作为地址访问内存元素
所以这个算法的asm伪代码可以是这样的:
开始假设r3存有预处理序列的起始地址,r4是序列元素数量
mov r1,r3
mov r2,r4
:LOOP
push.a [r1]
inc r1
dec r2
cmp r2,r0//r0=0
jmp.ifA>B LOOP
//上面的代码将序列压入栈
pop r1
cmp r1,$a
jmp.ifA>B BRC
push.b r1
pop.a r1
:BRC
push.b $a
pop.a r0//r0是垃圾桶
啊啊不想写了。总之这样一直遍历一遍最后r1里面是最小元素。stack.a清空。stack.b装了剩下的元素,然后翻转stack名字,重复这样就可以了。不是什么很高效的算法,但是懒得考虑太多就拿这个参考了。
其实这一段也可以直接用于switch语句实现。

然后想想寻路可能用到的算法。
A*!当然完整的a*对于这个计算机还是有点呛。
而且看起来没啥好优化的地方。。。
一种算法上的优化可能是舍去openlist中不必或不大可能搜索到节点。
a*会维护一个openlist数据结构,然后启发式的度量函数。总的来说没啥明显可以优化的吧。。大概。但是显然用到了很大的stack空间。对于此需要考虑是否做准备

楼主 savenseg  发布于 2019-05-04 10:04:00 +0800 CST  
这些算法也许会经常用到,所以可能被整到一个lib里面供所有程序调用。
除了上考虑的
排序,寻路,switch。
还有一个值得考虑的是二维数组中结构的比较,比如五子棋是否五个连起来。
得尽量保证程序中这个算法的搜索域不大,否则玩家会很痛苦。
例如五子棋,可以通过一个ptr加上偏移量,然后进行连续的cmp比较,只要出现了一个例外,就可以跳出loop。如果一直都挑不出来的话,就说明结构得到匹配了。很轻松。但是涉及不少访存,不知道能不能流畅运行。。。

楼主 savenseg  发布于 2019-05-04 10:14:00 +0800 CST  

楼主:savenseg

字数:26214

发表时间:2019-05-03 05:22:00 +0800 CST

更新时间:2020-06-01 12:02:37 +0800 CST

评论数:575条评论

帖子来源:百度贴吧  访问原帖

 

热门帖子

随机列表

大家在看