课程内容输入 02 要以课程内容输入 01 为载体讲的,根据一个简单的cmd完成客户的指令输入和计算机和处理表明。
-- Alex Chadwick
课程内容输入 02 要以课程内容输入 01 为载体讲的,根据一个简单的cmd完成客户的指令输入和计算机和处理表明。文中假如你已具备 课程内容11:输入01 的电脑操作系统代码基础。
1、终端绝大多数的电脑操作系统都以字符终端表明启动。经典白底黑字,根据电脑键盘输入电子计算机要实施的指令,然后就会提醒你语法错误,或是正好获得自己想要的执行结果。此方法有两种主要特点:按键和显示屏能够提供简单、强壮的电子计算机互动体制,绝大多数的计算机软件都是采用这一体制,这个其实普遍被网站管理员运用。
早期测算一般是在一栋楼里的一个巨型计算机系统软件,它有许多能够输指令的'终端'。电子计算机先后实行不一样的来源指令。
使我们分析一下真正想要什么信息内容:
电子计算机打开,表明热烈欢迎信息内容电子计算机启动时能接受输入标示客户从电脑键盘输入带参数指令客户输入回车或提交按钮电子计算机分析指令后实行可利用的指令电子计算机表明指令的执行结果,全过程信息内容循环系统跳转流程 2这种终端被界定为标准化的输入外部设备。用以(表明)输入的显示屏和输出打印的内容屏幕是同一个(LCTT 译注:最早期导出打印出真的是“打印出”到复印机/电传机的,而用以输入的终端仅仅电脑键盘,除非是进行了回显,不然导出终端一般不会表明输入的字符的)。换句话说终端应该是字符标注的一个抽象化。字符表明中,单独字符是最小模块,而非清晰度。显示屏被划分为固定不动总数不一样颜色的字符。我们可以在已有的显示屏代码基础上,先储存字符和相对应的颜色,然后用方式 DrawCharacter 把其传送到屏上。一旦我们应该字符表明,就只需在屏上绘制一行字符串。
新建文件名叫 terminal.s,如下所示:
.section .data
.align 4
terminalStart:
.int terminalBuffer
terminalStop:
.int terminalBuffer
terminalView:
.int terminalBuffer
terminalColour:
.byte 0xf
.align 8
terminalBuffer:
.rept 128*128
.byte 0x7f
.byte 0x0
.endr
terminalScreen:
.rept 1024/8 core.md Dict.md lctt2014.md lctt2016.md lctt2018.md LICENSE published README.md scripts sources translated 768/16
.byte 0x7f
.byte 0x0
.endr
这也是文档终端配置数据库文件。大家有两种最主要的储存自变量:terminalBuffer 和 terminalScreen。terminalBuffer 储存全部表明完的字符。它储存 128 行字符文字(1 行包括 128 个字符)。每一个字符有一个 ASCII 字符和颜色模块构成,初值为 0x7f(ASCII 的删掉字符)和 0(前景色和背景颜色为黑)。terminalScreen 储存现阶段屏幕上显示的字符。它储存 128x48 个字符,与 terminalBuffer 复位值一样。你可能觉得我仅必须 terminalScreen 就行了,为何还要terminalBuffer,其实也有2个益处:
我们可以非常容易见到字符串的转变,仅需绘制有所变化的字符。我们可以回退终端标注的历史时间字符,其实就是缓存的字符(受限制)这类与众不同技巧在功耗低系统中比较常见。画屏是最用时操作,所以我们仅仅在迫不得已的时候才会去执行这种操作。在这样一个系统中,我们可以随意更改 terminalBuffer,随后启用一个仅副本屏上字节数变动的方式。换句话说并不需要不断绘制每一个字符,那样能节省一大段转账文字的处理时间。
你总必须尝试去设计一个高效率的系统软件,若是在非常少转变的情形下这个模式会运转的迅速。
别的在 .data 段非常值得含意如下所示:
terminalStart 载入到 terminalBuffer 的第一个字符terminalStop 载入到 terminalBuffer 的最后一个字符terminalView 表明现阶段显示器的第一个字符,那样我们可以操纵滚动屏幕temrinalColour 将要被勾勒的字符颜色terminalStart 必须保存的原因是因为 termainlBuffer 是一个环形缓冲区。近义当缓冲区变满时,结尾地区会回退遮盖逐渐部位,那样最后一个字符成了第一个字符。所以我们需要把 terminalStart 向前推动,那样我们都知道己经布满他了。如何做到缓冲区检验:假如引索越境到缓冲区的结尾,就把引索偏向缓冲区的开端部位。环形缓冲区是一个常见的储存海量数据的高超方式,通常这些信息的近期一部分特别重要。它容许不受限制的载入,只确保近期一些特殊数据信息合理。这一经常用以信号分析和信息压缩算法。这样的状况,能够容许大家储存 128 行终端纪录,超出128行也不会有什么难题。要不是那样,当超出第 128 行后,我们应该把 127 行各自往前副本一次,这样很消耗时间。
表明 Hellow world 插进到尺寸为5的循环系统缓冲区的平面图。
环形缓冲区是算法设计一个事例。这是一个机构数据信息思路,有时候我们可以通过手机软件完成这类构思。
之前就已经讲过 terminalColour 几次了。你能依据他们的想法完成终端颜色,但是这个文字终端有 16 个前景色和 16 个背景颜色(这儿等同于有 162 = 256 种组成)。 CGA 终端的颜色界定如下所示:
报表 1.1 - CGA 颜色编号
编号颜色 (R, G, B)0黑 (0, 0, 0)1蓝 (0, 0, ?)2绿 (0, ?, 0)3青绿色 (0, ?, ?)4鲜红色 (?, 0, 0)5品红 (?, 0, ?)6深棕色 (?, ?, 0)7浅灰 (?, ?, ?)8深灰色 (?, ?, ?)9浅蓝色 (?, ?, 1)10浅绿色 (?, 1, ?)11青绿色 (?, 1, 1)12暗红色 (1, ?, ?)13浅品红 (1, ?, 1)14淡黄色 (1, 1, ?)15乳白色 (1, 1, 1)
我们将要前景色储存到颜色的低字节,背景颜色储存到颜色高字节。除开深棕色,别的这种颜色遵照一种方式如二进制的上位比特犬意味着提升 ? 到各个部件,别的比特犬意味着提升 ? 到分别部件。这样容易开展 RGB 颜色变换。
深棕色做为取代色(黑黄色)即不吸引眼球都没有什么用。
我们应该一个方法从 TerminalColour 载入颜色编号的四个比特犬,随后用 16 比特犬等效电路主要参数启用 SetForeColour。试着你完成。如果你感觉不便或是都还没进行显示屏系列课程,我们自己的完成如下所示:
2、文字表明.section .text
TerminalColour:
teq r0,#6
ldreq r0,=0x02B5
beq SetForeColour
tst r0,#0b1000
ldrne r1,=0x52AA
moveq r1,#0
tst r0,#0b0100
addne r1,#0x15
tst r0,#0b0010
addne r1,#0x540
tst r0,#0b0001
addne r1,#0xA800
mov r0,r1
b SetForeColour
我们自己的终端第一个真正想要的办法是 TerminalDisplay,它用于把现阶段的数据信息从 terminalBuffer拷到 terminalScreen 和具体的显示屏。如上所述,用这种方法一定要最少花销操作,由于我们应该经常启用它。它关键较为 terminalBuffer 与 terminalDisplay 的文字,随后只副本存在差异的字节数。一定要记住 terminalBuffer 要以环形缓冲区运转的,这样的事情,也是从 terminalView 到 terminalStop,或是 128*48 个字符,需看哪一个的更快。假如我们碰到 terminalStop,我们将假设在此之后的所有字符是 7f16 (ASCII 删掉字符),颜色为 0(灰黑色前景色和背景颜色)。
让我们一起看看务必要做的事:
载入 terminalView、terminalStop 和 terminalDisplay 地址。针对每一行:针对每一列:假如 terminalView 并不等于 terminalStop,依据 terminalView 载入现阶段字符和颜色不然载入 0x7f 和颜色 0从 terminalDisplay 载入现阶段的字符假如字符和颜色同样,立即跳转到第 10 步储存字符和颜色到 terminalDisplay用 r0 做为背景颜色主要参数启用 TerminalColour用 r0 = 0x7f(ASCII 删掉字符,一个块)、 r1 = x、r2 = y 启用 DrawCharacter用 r0 做为前景色主要参数启用 TerminalColour用 r0 = 字符、r1 = x、r2 = y 启用 DrawCharacter对位置参数 terminalDisplay 累加 2假如 terminalView 并不等于 terminalStop,terminalView 位置参数累加 2假如 terminalView 部位已是文档油压缓冲器的结尾,把它设为缓冲区的开端部位x 座标提升 8y 座标提升 16尝试去自身完成吧。假如你遇到困难,我们自己的计划方案下边给出来:
1、这里我的自变量有点乱。为了更好地考虑,我就用 taddr 储存 textBuffer 的结尾部位。
.globl TerminalDisplay
TerminalDisplay:
push{r4,r5,r6,r7,r8,r9,r10,r11,lr}
x .req r4
y .req r5
char .req r6
col .req r7
screen .req r8
taddr .req r9
view .req r10
stop .req r11
ldr taddr,=terminalStart
ldr view,[taddr,#terminalView - terminalStart]
ldr stop,[taddr,#terminalStop - terminalStart]
add taddr,#terminalBuffer - terminalStart
add taddr,#128*128*2
mov screen,taddr
2、从 yLoop 运行。
mov y,#0