DAY 21
1. 进度记录
- 用C语言编写应用程序:需要通过汇编调用系统API,然后将目标文件与汇编文件链接
- 通过区分应用程序与操作系统的代码段、数据段来保护操作系统。
- 对异常的支持
2. 学习与总结
(1)操作系统与应用程序
用途 | 段号 |
---|---|
操作系统代码段 | 2 |
操作系统数据段 | 1 |
应用程序代码段 | 1003 |
应用程序数据段 | 1004 |
TSS使用 | 3~1002 |
(2)异常
- 当操作系统发现应用程序出现异常时,自动产生0x0d号中断。
(3)访问权限
- 操作系统不能CALL应用程序,也就是系统段代码无法访问应用段。可以用RETF替代far-JMP的功能,从而实现调用。
DAY 20
1. 进度记录
- 制作API:显示单个字符、显示字符串
2. 成果与总结
(1)API制作流程
- 将 asm_hrb_api 注册到 IDT(0x40),应用程序将通过中断号调用asm_hrb_api。同时asm_hrb_api使用EDX作为功能号寄存器,因此在调用时可指定功能号以调用不同功能。
- asm_hrb_api 调用 _hrb_api
- hrb_api 根据 EDX 调用不同API
中断返回:IRETD
(2)farcall
- 调用时与farjmp一样,只需指定段和偏移量
eg: CALL 2*8:0xbe3
或CALL FAR [ESP+4]
- 返回不用RET, 用RETF
(3)API
功能号 | 功能 |
---|---|
1 | 显示单个字符(AL=字符编码) |
2 | 显示字符串(EBX=字符串地址) |
3 | 显示字符串(EBX=字符串地址,ECX=字符串长度) |
DAY 19
1. 进度记录
- type: 查询文件目录表找到文件控制块,然后读取文件并显示
- 增加对制表符(0x09)、换行符(0x0a)、回车符(0x0d)的支持
- 对FAT的支持
- 代码整理,new console.c, window.c, file.c
- 创建一个应用程序 hal,并通过命令行加载
2. 成果与总结
(1)FAT
- 位于柱面0,磁头0,扇区2开始的9个扇区中,相当于0x000200~0x0013ff
- 磁盘中备份了两份FAT,第一份位于0x000200~0x0013ff, 第二份位于ox001400~0x0025ff
(2)文件格式 hrb
相当于exe,为了与exe区分
(3)段分配
范围 | |
---|---|
dsctbl.c | 1~2 |
mtask.c | 3~1002 |
应用程序 | 1003~ |
(4)应用程序启动流程(例:hello)
- 将hello.nas 翻译成 hello.hrb, 并写入磁盘中
- 根据名称找到文件控制块
- 根据文件控制块和FAT找到所在所在磁盘并写入内存
- 分配一个段(内存地址和长度等信息),注册到GDT中
- farcall 执行这个段的程序
DAY 18
1. 进度记录
- 光标控制,使用TAB切换窗口同时切换光标。向缓冲区写入2–光标ON, 3–光标OFF
- 对回车键的支持(ASCII: 10)
- 对窗口滚动的支持
- mem命令
- cls 命令
- dir命令
2. 学习与总结
(1)文件管理
- 文件体:
struct FILEINFO {
unsigned char name[8], ext[3], type;
char reserve[10];
unsigned short time, date, clustno;
unsigned int size;
};
- 存放位置 ADR_DISKIMG:0x2600~0x4200, 共224个
- type(属性)
值 | 类型 |
---|---|
0x01 | 只读文件 |
0x02 | 隐藏文件 |
0x04 | 系统文件 |
0x08 | 非文件信息(比如磁盘名称) |
0x10 | 目录 |
注 | 当同时具有多个属性,只需相加即可 |
DAY 17
1. 进度记录
- 通过创建 idle 任务,避免在所有LEVEL 中都没有任务时出现问题
- 创建命令行窗口
- TAB切换窗口
- 实现 Shift 的功能
- 通过判断 Shift 和 CapsLock的状态,实现大小写字母的输入
2. 成果与总结
3. 问题
(1) 没有真正实现大小写字母的切换
(2)键盘编码顺序还有问题
DAY 16
1. 进度记录
- 改进任务管理,调用task_alloc 可直接分配任务
- 让任务休眠
- 通过增加窗口数量测试多任务
- 设定任务管理优先级
2. 成果与总结
DAY 15
1. 进度记录
- 任务切换
- 自动任务切换
2. 成果与总结
(1)JMP
-
只改写EIP 的称为near模式,同时改写EIP、CS的成为far模式
-
当所指定的目标地址段不是可执行代码段,而是TSS的话,CPU会将此指令理解为任务切换
eg: JMP 4*8:0
(2)TR
- TR指向GDT中的TSS描述符,在给TR赋值时,需将GDT编号乘 8
(3)函数调用时的参数存放位置
调用函数,如farjmp(int eps, int cs) 时,[ESP+4]存放第一个 参数的值,[ESP+8存放第二个参数的值]
3.补充学习
(1)TSS
struct TSS32 {
int backlink, esp0, ss0, esp1, ss1, esp2, ss2, cr3;
int eip, eflags, eax, ecx, edx, ebx, esp, ebp, esi, edi;
int es, cs, ss, ds, fs, gs;
int ldtr, iomap;
};
- LINK: LINK存放现行任务的父任务的TSS选择符,与EFLAGS中的NT位配合实现任务嵌套,任务转换时NT=1
- ESPi, SSi: SS0:ESP0、SS1:ESP1、SS2:ESP2 分别为3个内层堆栈的指针,指向0–2级堆栈栈顶。可实现堆栈跟随任务转换,以便从内向外返回时恢复外层堆栈信息。