├── LICENSE ├── README.md ├── document ├── link.txt └── report.txt ├── fat12 ├── disk.h ├── disk.img ├── readfat12.cpp └── rw.cpp ├── game ├── Makefile ├── ReadMe.txt ├── bochsrc.bxrc ├── include │ ├── color.asm │ ├── disk.asm │ ├── keyboard.asm │ ├── map0.asm │ ├── map3.asm │ └── rand.asm ├── pic │ ├── 2.png │ ├── 3.png │ ├── boss.png │ ├── fbqqt.png │ ├── g.png │ ├── lose.png │ ├── people.png │ ├── power.png │ ├── qqt.png │ ├── title.png │ ├── title2.png │ ├── wallpaper_07_800.jpg │ ├── wallpaper_07_800.png │ ├── wallpaper_07_800.xcf │ └── win.png ├── report │ ├── 14348134吴侃-汇编HappyQQT.docx │ └── 14348134吴侃-汇编HappyQQT.pdf ├── res │ ├── boss.asm │ ├── football.asm │ ├── huoying.asm │ ├── lose.asm │ ├── mappic.asm │ ├── people.asm │ ├── power.asm │ ├── title.asm │ └── win.asm ├── source │ ├── ai.c │ ├── kernel.asm │ └── loadknl.asm └── tools │ ├── key.cpp │ ├── key.txt │ ├── makemap.cpp │ └── tu.py ├── lab1 ├── 14348134吴侃 │ ├── 14348134吴侃.pdf │ └── wkcn.asm └── pic │ └── frame.png ├── lab2 ├── 14348134os.asm ├── 14348134吴侃 │ └── 操作系统原理实验二.pdf ├── report │ ├── 3.png │ └── report.txt ├── wkcn.asm ├── wkcn1.asm ├── wkcn2.asm ├── wkcn3.asm ├── wkcn4.asm └── 操作系统原理实验二.docx ├── lab3 ├── Makefile ├── ReadMe.txt ├── bochsrc.bxrc ├── include │ ├── defines.h │ ├── io.h │ └── string.h ├── kan.asm ├── kernel.asm ├── loader.asm ├── os.cpp ├── pic │ ├── 2.png │ └── 4.png ├── report │ └── 14348134吴侃lab3.pdf ├── wkcn1.asm ├── wkcn2.asm ├── wkcn3.asm └── wkcn4.asm ├── lab4 ├── Makefile ├── ReadMe.txt ├── bochsrc.bxrc ├── bpb.cpp ├── bs.cpp ├── header.asm ├── hello.cpp ├── include │ ├── defines.h │ ├── disk.h │ ├── io.h │ ├── keyboard.h │ └── string.h ├── kan.asm ├── kernel.asm ├── linker_100.ld ├── loadknl.asm ├── ls.cpp ├── os.cpp ├── pic │ ├── bpb.png │ ├── bs.png │ └── ls.png ├── report │ ├── 14348134吴侃lab4.pdf │ └── rep.txt ├── tools │ ├── key.cpp │ ├── key.txt │ └── keybuild ├── wkcn1.asm ├── wkcn2.asm ├── wkcn3.asm └── wkcn4.asm ├── lab5 ├── Makefile ├── ReadMe.txt ├── alpha.cpp ├── bochsout.txt ├── bochsrc.bxrc ├── box.asm ├── bpb.cpp ├── bs.cpp ├── clock.cpp ├── counter ├── counter.cpp ├── fork1.cpp ├── fork2.cpp ├── header.asm ├── hello.cpp ├── hello.s ├── help.cpp ├── include │ ├── defines.h │ ├── disk.h │ ├── interrupt.h │ ├── io.h │ ├── keyboard.h │ ├── port.h │ ├── string.h │ ├── task.h │ └── version.h ├── inttest.asm ├── kan.asm ├── kernel.asm ├── linker_100.ld ├── loadknl.asm ├── ls.cpp ├── os.cpp ├── ouch.cpp ├── pic │ ├── 51.png │ └── 54.png ├── report │ └── 14348134吴侃lab5_ver2.pdf ├── tools │ ├── key.cpp │ ├── key.txt │ └── keybuild ├── wkcn1.asm ├── wkcn2.asm ├── wkcn3.asm └── wkcn4.asm ├── lab6 ├── .ycm_extra_conf.py ├── Makefile ├── ReadMe.txt ├── bochsrc.bxrc ├── counter ├── include │ ├── defines.h │ ├── disk.h │ ├── fork.h │ ├── interrupt.h │ ├── io.h │ ├── keyboard.h │ ├── mem_base.h │ ├── memory.h │ ├── os_sem.h │ ├── pcb.h │ ├── port.h │ ├── sem.h │ ├── string.h │ ├── thread.h │ └── version.h ├── pic │ ├── 1.png │ ├── 2.png │ └── 3.png ├── report │ ├── 14348134吴侃lab6.docx │ └── 14348134吴侃lab6.pdf ├── source │ ├── alpha.cpp │ ├── box.asm │ ├── bpb.cpp │ ├── bs.cpp │ ├── counter.cpp │ ├── fork1.cpp │ ├── fork2.cpp │ ├── fruit.cpp │ ├── header.asm │ ├── help.cpp │ ├── kan.asm │ ├── kernel.asm │ ├── letter.cpp │ ├── linker_100.ld │ ├── loadknl.asm │ ├── ls.cpp │ ├── mat.cpp │ ├── os.cpp │ ├── testint.asm │ ├── testnew.cpp │ ├── testport.cpp │ ├── testst.cpp │ ├── wkcn1.asm │ ├── wkcn2.asm │ ├── wkcn3.asm │ └── wkcn4.asm └── tools │ ├── key.cpp │ ├── key.txt │ ├── keybuild │ └── mem.cpp ├── lab7 ├── ReadMe.txt ├── pic │ ├── 1.png │ └── 2.png └── report │ └── 14348134吴侃lab7.pdf ├── lab8 ├── .ycm_extra_conf.py ├── Makefile ├── ReadMe.txt ├── bochsrc.bxrc ├── include │ ├── defines.h │ ├── disk.h │ ├── disk_op.h │ ├── fork.h │ ├── fstream.h │ ├── interrupt.h │ ├── io.h │ ├── keyboard.h │ ├── mem_base.h │ ├── memory.h │ ├── msg.h │ ├── msg_base.h │ ├── os_msg.h │ ├── os_sem.h │ ├── pcb.h │ ├── port.h │ ├── portsList.h │ ├── prog.h │ ├── screen.h │ ├── sem.h │ ├── string.h │ ├── thread.h │ └── version.h ├── pic │ ├── 1.png │ ├── 2.png │ └── 3.png ├── report │ ├── 14348134吴侃lab8.docx │ └── 14348134吴侃lab8.pdf └── source │ ├── alpha.cpp │ ├── box.asm │ ├── bpb.cpp │ ├── bs.cpp │ ├── counter.cpp │ ├── fork1.cpp │ ├── fork2.cpp │ ├── fruit.cpp │ ├── header.asm │ ├── help.cpp │ ├── kan.asm │ ├── kernel.asm │ ├── letter.cpp │ ├── linker_100.ld │ ├── loadknl.asm │ ├── ls.cpp │ ├── mat.cpp │ ├── os.cpp │ ├── screen.cpp │ ├── shell.cpp │ ├── testnew.cpp │ ├── testport.cpp │ ├── testst.cpp │ ├── wkcn1.asm │ ├── wkcn2.asm │ ├── wkcn3.asm │ └── wkcn4.asm ├── toShirley.asm └── wkcn.asm /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016-2017 wkcn 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /document/link.txt: -------------------------------------------------------------------------------- 1 | Linux 下制作虚拟软盘镜像 2 | http://wenix.blog.51cto.com/874806/364816 3 | linux下dd命令详解 4 | http://www.cnblogs.com/licheng/archive/2008/03/21/1116492.html 5 | - 作者:(美国)马兹迪(Muhammad Ali Mazidi) (美国)考西(Danny Causey) (美国)马兹迪(Janice Gillispie Mazidi) 译者:高升 合著者:王筱珍 6 | - 李 7 | 忠 王晓波 余 洁 著 8 | <操作系统原理实验课件 - 实验1> - 凌应标 9 | 10 | 11 | -------------------------------------------------------------------------------- /document/report.txt: -------------------------------------------------------------------------------- 1 | 实验题目: 2 | 接管裸机的控制权 3 | 4 | 实验目的: 5 | 学习如何搭建和应用实验环境,编写一个简单的汇编程序,让它接管裸机的控制权. 6 | 7 | 实验要求: 8 | 搭建和应用实验环境 9 | 虚拟机安装,生成一个基本配置的虚拟机XXXPC和多个1.44MB容量的虚拟软盘,将其中一个虚拟软盘用DOS格式化为DOS引导盘,用WinHex工具将其中一个虚拟软盘的首扇区填满你的个人信息。 10 | 接管裸机的控制权 11 | 设计IBM_PC的一个引导扇区程序,程序功能是:用字符‘A’从屏幕左边某行位置45度角下斜射出,保持一个可观察的适当速度直线运动,碰到屏幕的边后产生反射,改变方向运动,如此类推,不断运动;在此基础上,增加你的个性扩展,如同时控制两个运动的轨迹,或炫酷动态变色,个性画面,如此等等,自由不限。还要在屏幕某个区域特别的方式显示你的学号姓名等个人信息。将这个程序的机器码放进放进第三张虚拟软盘的首扇区,并用此软盘引导你的XXXPC,直到成功。 12 | 13 | 实验方案: 14 | 分为XXX个步骤 15 | 16 | 实验环境: 17 | 物理机操作系统: Arch Linux 4.4.1-2 18 | 虚拟机软件: VMware Workstation 12 Pro 19 | 虚拟机配置: CPU: i7-4702MQ @ 2.20GHz, 使用单核单线程 20 | 内存:4 MB 21 | 硬盘:32 MB 22 | 23 | 24 | 实验工具 25 | 编辑器: Vim 7.4 26 | 汇编工具: NASM 2.11.08 27 | 软盘镜像生成工具: dd, WinImage 28 | 软盘镜像刻入工具: DiskWriter 29 | 十六进制编辑器: gHex, WinHex 30 | 使用wine 1.9.4 运行Windows平台软件 31 | 32 | 实验方案: 33 | 虚拟机配置方法: 34 | 35 | 由于使用虚拟机做操作系统实验有方便快速安全的特点,因此使用VMWare 36 | Workstation构建一个虚拟机平台. 该虚拟机平台的配置为单核单线程CPU, 4MB内存, 37 | 32MB硬盘. 38 | 39 | 40 | NASM汇编工具及编辑器vim的设置: 41 | NASM是一个汇编工具, 能将汇编代码编译成对应二进制代码. 42 | 使用命令nasm xxx.asm即可对xxx.asm汇编文件进行编译, 生成对应二进制文件xxx. 43 | 为了使得操作方便,可以在vim的配置上编写按F5时执行exec "!nasm ".file_name 44 | 45 | 十六进制编辑器: 46 | WinHex和gHex分别是Windows平台和Linux平台的十六进制编辑器, 47 | 它们可以以二进制的方式打开任意文件,并且修改文件中的二进制值. 48 | 这里使用十六进制编辑器查看软盘映像的二进制值(是否存在0x55aa), 49 | 以及将编译出的文件粘贴到软盘镜像中. 50 | 使用vim的%!xxd 和 %!xxd -r 也能很容易地在十六进制和文本模式切换. 51 | DiskWriter能将二进制文件一键写入到软盘映像中,其原理为将二进制文件直接拷贝到软盘映像的首部. 52 | 53 | 实验操作1: 54 | 搭建和应用实验环境 55 | 创建方式为: 56 | 选项卡 File -> New Virual Machine, 在"New Virual Machine 57 | Wizard"中可以设置虚拟机硬件参数, 58 | 在完成创建后,移除网络适配器(本次实验不会使用到网络),创建虚拟机完成. 59 | 其中,虚拟机的名字为14348134-PC 60 | [pic1-vmwareconfig] 61 | 62 | 创建多个1.44MB容量的虚拟软盘 63 | 64 | 1.44MB虚拟软盘参数: 65 | 2面、80道/面、18扇区/道、512字节/扇区 66 | 扇区总数=2面 X 80道/面 X 18扇区/道 = 2880扇区 67 | 存储容量= 512字节/扇区X 2880扇区 = 1440 KB =1474560B 68 | 69 | 这里有两种方式创建虚拟软盘 70 | 1. 使用dd命令: 71 | dd if=/dev/zero of=floppy.img bs=512 count=2880 72 | 其中, bs为读/写缓冲区大小,单位为byte; count为写入的块数. 73 | if为输入文件名, 这里填入0 74 | 75 | 2. 使用WinImage生成 76 | File -> New, 在Standard format中选择1.44MB, 选择OK 77 | 然后Save保存, 此时文件类型选择Image file(*.ima), 文件名为xxx.img, 78 | 用gHex打开该文件,可以发现510~511字节偏移处, 十六进制分别为55, AA. 79 | 这是一个可以在裸机环境执行的镜像. 80 | 81 | 装载软盘镜像到虚拟机中, 点击虚拟机中的Edit virtual machine settings -> Add -> 82 | Floppy Drive -> Use a floppy image, 选择镜像文件即可. 83 | 或者在已创建的软盘设备上选择镜像文件. 84 | 需要勾选Connect at power on. 85 | 86 | 将一个虚拟软盘用Dos格式化为Dos引导盘 87 | 同时使用两个虚拟软盘设备载入一个空的软盘镜像和Dos系统镜像, 进入Dos后输入: 88 | 即可格式化. 89 | 90 | 用WinHex工具将其中一个虚拟软盘的首扇区填满你的个人信息。 91 | 一个虚拟软盘的首扇区为软盘映像文件的前510个字节+0x55aa. 92 | 使用WinHex打开软盘映像后, 选择 93 | 94 | 2.接管裸机的控制权 95 | 96 | 算法: 97 | 为了使一个字符能从屏幕左边某行45度角下斜射出,保持一个适当速度移动,并且碰到边缘能够反射.这里使用位置-速度的方法, 98 | 即位置代表字符当前在屏幕的位置, 速度代表字符下一步的位移. 99 | 初始时,位置s为(x,y),速度v为(1,1) 100 | 每次运动时, new_s = s + v, 101 | 当触碰到边缘时, 速度中指向边缘的方向取反,即下一步要反弹. 102 | 103 | 104 | 文字显示 105 | 显存段地址B800h, 从这个位置开始, 106 | 每两个字节的低位字节决定要显示的字,高位字节决定这个字的颜色等显示状态. 107 | 文本显示的范围为25行80列. 108 | 偏移量 = ((行数(从0开始) * 80 ) + 25 ) * 2 109 | 即要显示的字的内存位置 110 | 111 | 112 | 数据段ds 113 | 主引导扇区数据为512字节 114 | 处理器会将主引导扇区的数据加载到逻辑地址0x0000:0x7c00中, 115 | 然后检测最后两字节是否为0x55和0xAA, 若存在则主引导扇区有效, 以一个段间转移指令 jmp 0x0000:0x7c00 跳到那里继续执行 116 | 117 | 118 | 存储 119 | -------------------------------------------------------------------------------- /fat12/disk.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/fat12/disk.img -------------------------------------------------------------------------------- /fat12/readfat12.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/fat12/readfat12.cpp -------------------------------------------------------------------------------- /fat12/rw.cpp: -------------------------------------------------------------------------------- 1 | #include "disk.h" 2 | 3 | char data[204800]; 4 | int si = 0; 5 | int main(){ 6 | File file; 7 | file.open("WACK EXE"); 8 | if (1){ 9 | 10 | ifstream fin("test"); 11 | char c; 12 | c = fin.get(); 13 | while(!fin.eof()){ 14 | data[si++] = c; 15 | c = fin.get(); 16 | } 17 | file.write(data,si); 18 | }else{ 19 | file.read(data, file.size()); 20 | for (int i = 0;i < file.size();++i){ 21 | cout < 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | struct K{ 8 | string name; 9 | string smm[4]; 10 | string asc[4]; 11 | }; 12 | 13 | int main(){ 14 | ifstream fin("key.txt"); 15 | string name; 16 | string temp; 17 | 18 | vector ks; 19 | do{ 20 | K k; 21 | fin >> name; 22 | if(fin.eof())break; 23 | for (int i = 0;i < name.size();++i){ 24 | char c = name[i]; 25 | if (c >= 'a' && c <= 'z')c = c - 'a' +'A'; 26 | k.name += c; 27 | } 28 | for (int i = 0;i < 4;++i){ 29 | fin >> k.smm[i]; 30 | fin >> k.asc[i]; 31 | } 32 | ks.push_back(k); 33 | }while(!fin.eof()); 34 | ofstream fout("keyboard.asm"); 35 | //fout << "#ifndef _KEY_BOARD_H_" << endl; 36 | //fout << "#define _KEY_BOARD_H_" << endl << endl; 37 | int o = 0; 38 | for (size_t i = 0;i < ks.size();++i){ 39 | K &k = ks[i]; 40 | string name = "KEY_" + k.name; 41 | //fout << "#define " << name << " " << "0x" << k.smm[o] << k.asc[o] << endl; 42 | fout << name << " equ " << "0x" << k.smm[o] << k.asc[o] << endl; 43 | } 44 | o = 1; 45 | for (size_t i = 0;i < ks.size();++i){ 46 | K &k = ks[i]; 47 | string name = "KEY_SHIFT_" + k.name; 48 | fout << name << " equ " << "0x" << k.smm[o] << k.asc[o] << endl; 49 | //fout << "#define " << name << " " << "0x" << k.smm[o] << k.asc[o] << endl; 50 | } 51 | o = 2; 52 | for (size_t i = 0;i < ks.size();++i){ 53 | K &k = ks[i]; 54 | string name = "KEY_CTRL_" + k.name; 55 | //fout << "#define " << name << " " << "0x" << k.smm[o] << k.asc[o] << endl; 56 | fout << name << " equ " << "0x" << k.smm[o] << k.asc[o] << endl; 57 | } 58 | o = 3; 59 | for (size_t i = 0;i < ks.size();++i){ 60 | K &k = ks[i]; 61 | string name = "KEY_ALT_" + k.name; 62 | //fout << "#define " << name << " " << "0x" << k.smm[o] << k.asc[o] << endl; 63 | fout << name << " equ " << "0x" << k.smm[o] << k.asc[o] << endl; 64 | } 65 | fout << endl << endl << "#endif" << endl; 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /game/tools/makemap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | //320 x 240 5 | // / 16 6 | //20 x 15 7 | int main(){ 8 | ofstream fout("map.asm"); 9 | for (int r = 0;r < 15;++r){ 10 | fout << "db "; 11 | for (int c = 0;c < 20;++c){ 12 | if (c != 0)fout << ", "; 13 | if (c % 2 == 0){ 14 | fout << 0; 15 | }else{ 16 | fout << 1; 17 | } 18 | } 19 | fout << endl; 20 | } 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /game/tools/tu.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | # 256色 3 | from PIL import Image 4 | from numpy import * 5 | from scipy.misc import * 6 | 7 | #需要修改! 8 | picw = 320 9 | pich = 200 10 | picr = 1 11 | picc = 1 12 | im = array(Image.open('title2.png')) 13 | #imshow(im) 14 | pim = Image.fromarray(uint8(im)) 15 | #print im.shape 16 | im = array(pim.resize((picw * picc,pich * picr))) 17 | Ihigh = 255 18 | Ilow = 0 19 | Imed = (Ihigh + Ilow) / 2 20 | 21 | def ToHex(c): 22 | u = 0 23 | b = 1 24 | #RGBA -> ARGB 25 | for i in [2,1,0,3]: 26 | if c[i] >= Imed: 27 | u += b 28 | b*=2 29 | t = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'] 30 | return t[u] 31 | 32 | fout = open("title.asm",'w') 33 | 34 | def Draw(x,y): 35 | for i in range(y * pich, y * pich+ pich): # row 36 | fout.write("db ") 37 | count = 0 38 | for j in range(x*picw,x*picw+picw): #col 39 | color = im[i][j] 40 | b = 1 41 | res = 0 42 | #for y in [2,1,0,3]: 43 | #256色8 bits 44 | #各种颜色2bit 45 | #u = color[y] 46 | #u = int(u) / (256 / 4) 47 | #if u >= 4: 48 | # u = 3 49 | #res += u * b 50 | #b *= 4 51 | #if color[3] < Imed: 52 | # color = (255,0,255,255) 53 | res = int((int(color[0])&0xe0) | ((int(color[1])>>3)&0x1c) | ((int(color[2])>>6)&0x03)) 54 | fout.write(str(hex(res))) 55 | if j != x * picw + picw: 56 | fout.write(', ') 57 | 58 | fout.write('\n') 59 | 60 | for y in range(picr): 61 | for x in range(picc): 62 | Draw(x,y) 63 | -------------------------------------------------------------------------------- /lab1/14348134吴侃/14348134吴侃.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab1/14348134吴侃/14348134吴侃.pdf -------------------------------------------------------------------------------- /lab1/14348134吴侃/wkcn.asm: -------------------------------------------------------------------------------- 1 | ;Running Ball 2 | ;Jackie Wu (Wu Kan) 3 | ;14348134 4 | ;wkcn@live.cn 5 | 6 | ;totalDelay = outDelay * inDelay 7 | outDelay equ 50000 8 | inDelay equ 1800 9 | 10 | MAX_X equ 80 11 | MAX_Y equ 25 12 | 13 | ;set data segment 14 | mov ax,07c0h 15 | mov ds,ax 16 | 17 | ;text window 18 | ;25 * 80 19 | mov ax,0B800h 20 | mov es,ax 21 | 22 | 23 | %macro SINGLE 4 24 | ;pos dw 0000h ;from 0,0 25 | ;vel dw 0101h ;v = (1,1) 26 | ;char db '*' 27 | ;color db 07H 28 | 29 | mov ax, [%1] 30 | mov [pos], ax 31 | mov ax, [%2] 32 | mov [vel], ax 33 | mov al, [%3] 34 | mov [char], al 35 | mov al, [%4] 36 | mov [color], al 37 | 38 | call PLAY 39 | 40 | mov ax, [pos] 41 | mov [%1], ax 42 | mov ax, [vel] 43 | mov [%2], ax 44 | %endmacro 45 | 46 | START: 47 | call DELAY 48 | call PLAY 49 | SINGLE pos1,vel1,char1,color1 50 | SINGLE pos2,vel2,char2,color2 51 | SINGLE pos3,vel3,char3,color3 52 | call SHOWNAME 53 | jmp START 54 | 55 | PLAY: 56 | call SETPOINTER 57 | call ELIMINATE 58 | 59 | call UPDATEPOS 60 | 61 | call SETPOINTER 62 | call SHOW 63 | ret 64 | 65 | SHOWNAME: 66 | mov cx,[msgLen] 67 | 68 | mov si,message 69 | 70 | mov di, 12*80 + 50 71 | 72 | mov dl,[msgColor] 73 | 74 | printChar: 75 | mov al,[si] 76 | inc si 77 | mov ah,dl 78 | add dl,1 79 | mov [es:di],ax 80 | add di,2 81 | loop printChar 82 | 83 | inc byte[msgColor] 84 | 85 | ret 86 | 87 | DELAY: 88 | mov cx, outDelay 89 | LOOP1: 90 | mov ax, inDelay 91 | LOOP2: 92 | dec ax 93 | jg LOOP2 94 | loop LOOP1 95 | 96 | ret 97 | 98 | UPDATEPOS: 99 | ;parameter: pos, vel 100 | mov ax,[pos] 101 | mov bx,[vel] 102 | 103 | ;update x 104 | add ah,bh 105 | jne XNZ 106 | ;if x == 0 107 | mov bh,1 108 | XNZ: 109 | CMP ah,MAX_X-1 110 | jl XNF 111 | ;if x >= MAX_X-1 112 | mov bh,-1 113 | XNF: 114 | 115 | ;update y 116 | add al,bl 117 | jne YNZ 118 | ;if y == 0 119 | mov bl,1 120 | YNZ: 121 | CMP al,MAX_Y-1 122 | jl YNF 123 | ;if y >= MAX_Y-1 124 | mov bl,-1 125 | YNF: 126 | mov [pos],ax 127 | mov [vel],bx 128 | ret 129 | 130 | SETPOINTER: 131 | ;parameter pos, char 132 | mov ax, 0 133 | mov bx, [pos] ; bx = (x,y) 134 | mov al, bl 135 | mov cx, MAX_X 136 | mul cx ; ax *= MAX_X namely ax = y * MAX_X 137 | mov cx, 0 138 | mov cl, bh 139 | add ax, cx ; ax += x 140 | mov cx, 2 141 | mul cx 142 | mov bx, ax 143 | ret 144 | 145 | SHOW: 146 | ;new 147 | mov al, [char] 148 | mov ah, [color] 149 | mov [es:bx],ax 150 | ret 151 | 152 | ELIMINATE: 153 | ;clean 154 | mov ax, 0 155 | mov [es:bx],ax 156 | ret 157 | 158 | 159 | 160 | 161 | DATA: 162 | message db 'WuKan 14348134' 163 | msgLen dw $-message 164 | msgColor db 00h 165 | 166 | outCount dw outDelay 167 | inCount dw inDelay 168 | 169 | pos dw 0000h ;from 0,0 170 | vel dw 0101h ;v = (1,1) 171 | char db '*' 172 | color db 07H 173 | 174 | ;elements 175 | pos1 dw 0000h 176 | vel1 dw 0101h 177 | char1 db '*' 178 | color1 db 03H ;green 179 | 180 | pos2 dw 1010h 181 | vel2 dw 01FFh 182 | char2 db 'A' 183 | color2 db 0CFH ;twinkle red and light white 184 | 185 | pos3 dw 2019h 186 | vel3 dw 0FFFFh 187 | char3 db '@' 188 | color3 db 0EH ;yello 189 | 190 | times 510-($-$$) db 0 191 | dw 0xaa55 192 | -------------------------------------------------------------------------------- /lab1/pic/frame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab1/pic/frame.png -------------------------------------------------------------------------------- /lab2/14348134吴侃/操作系统原理实验二.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab2/14348134吴侃/操作系统原理实验二.pdf -------------------------------------------------------------------------------- /lab2/report/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab2/report/3.png -------------------------------------------------------------------------------- /lab2/report/report.txt: -------------------------------------------------------------------------------- 1 | 实验题目: 2 | 加载用户程序的监控系统 3 | 4 | 实验目的: 5 | 实现一个监控系统,能够运行不同的用户程序,并且能从用户程序返回监控系统. 6 | 7 | 实验要求: 8 | 设计四个(或更多)有输出的用户可执行程序 9 | 设计四个有输出的用户可执行程序,分别在屏幕1/4区域动态输出字符,如将用字符‘A’从屏幕左边某行位置45度角下斜射出,保持一个可观察的适当速度直线运动,碰到屏幕相应1/4区域的边后产生反射,改变方向运动,如此类推,不断运动;在此基础上,增加你的个性扩展,如同时控制两个运动的轨迹,或炫酷动态变色,个性画面,如此等等,自由不限。还要在屏幕某个区域特别的方式显示你的学号姓名等个人信息。 10 | 11 | 12 | 实验环境: 13 | 物理机操作系统: Arch Linux 4.4.3-1 14 | 虚拟机软件: VMware Workstation 12 Pro 15 | 虚拟机配置: CPU: i7-4702MQ @ 2.20GHz, 使用单核单线程 16 | 内存:4 MB 17 | 硬盘:32 MB 18 | 19 | 20 | 实验工具 21 | 编辑器: Vim 7.4 22 | 汇编工具: NASM 2.11.08 23 | C++编译器:clang++ 3.7.1 24 | 25 | 实验方案: 26 | 27 | 监控系统的实现: 28 | 监控系统为主引导程序, 当机器读取其主引导区时,将监控系统载入内存物理地址: 29 | 7c00h处, 验证主引导程序有效后(55aah), jmp 0x0000:0x7c00 30 | 31 | 监控程序调用用户程序: 32 | 33 | 将用户程序写入内存: 34 | 使用13H中断的02H功能, 即读取扇区功能. 35 | 设置要读取的扇区数量(ah), 驱动器号(dl), 磁头号(dh), 柱面号(ch),起始扇区号(cl). 36 | 其中, 磁头号和柱面号的起始编号都是0, 扇区号的起始编号为1. 37 | 磁头0,柱面0,扇区1为监控系统; 之后的是用户程序, 在这里, 38 | 我将用户程序放在磁头0,柱面0,扇区2之后包括扇区2的位置. 39 | 当设置好参数使用13H中断的02H功能后, 40 | 对应扇区中的程序将被写入一个固定的内存地址(偏移量为UserProgramOffset) 41 | 42 | 执行用户程序: 43 | 这里的实现方式为: 44 | 将用户程序写入内存后,将计算机的控制权交给用户程序,即跳转到用户程序存放的地址, 45 | 并开始执行用户程序. 46 | 47 | 用户程序的编写: 48 | 返回监控程序: 49 | 这里实现了两个软中断, int 20h和int 21h. 50 | 这里定义: 21h 软中断为直接返回监控程序; 51 | 20h 软中断为当按下Ctrl + Z时返回监控程序 52 | 由于使用了中断, 从裸机程序转为用户程序的改写非常简单, 53 | 只需要在用户程序的开头加上org 54 | 0a100h说明用户程序指令将被写入到内存从物理地址0a100h起始处, 55 | 然后在用户程序的循环中加入int 20h, 即使用软中断以提供返回监控程序功能. 56 | 用户程序实现: 57 | Running Ball(45度飞翔的字符): 58 | 在屏幕中设置了运动范围, 当字符碰到运动范围边缘时,改变对应的速度. 59 | 多个字符的运动采用了nasm宏实现类C++函数的技术. 60 | My Name: 61 | 使用类似函数的写法, 设置画笔的起始点(pos), 运动方向(vel), 以及画的点数(cx) 62 | 63 | 键盘中断 64 | 键盘中断为16h, 当ah设置为01h时, 即检测按键. 当有键被按下, ZF = 0; 65 | 如果没有键被按下, ZF = 1. ZF位表示结果是否为零. 使用jz可以处理没有按键的状态. 66 | 当有键被按下, 设置ah为00h, 再次调用16h中断, 按下的键的扫描码存放在ah中,ascii 67 | 码存放在al中. 经查表, ctrl + z的对应扫描码为2c1ah. 68 | 如果不调用16h中断的00h功能, 键盘缓冲区的按键信息将不会被清除. 69 | 70 | 中断向量表 71 | 实模式下的中断向量表的入口点集中存放在内存从物理地址0x00000开始, 72 | 到0x003ff结束. 每个中断在中断向量表中占2个字, 73 | 分别为中断处理程序的偏移地址和段地址. 共256个中断, 中断i的入口点位于物理地址i 74 | * 4处. 75 | 76 | Writer: 77 | 使用C++编写了一个简易的文件合成程序, 使用./writer 14348134os wkcn1 wkcn2 wkcn3 78 | wkcn4 kan 79 | 命令, 即可将这些文件依次合并到disk.img文件. 80 | 81 | 小结: 82 | 返回思想 83 | 多任务设想 84 | 中断向量表 85 | 寄存器使用 86 | 用户程序错误 87 | 88 | 我觉得这次的实验, 难点在于如何在监控程序中调用用户程序, 89 | 并且能从用户程序中返回. 90 | 我开始的做法是, 使用call调用用户程序, 并且使用ret返回. 91 | 但这样有一个不足, 即用户程序需要编写一些代码以提供返回判断, 返回功能. 92 | 而且移植性不好, 比如当要修改返回判断时, 需要修改大量的程序. 因此, 93 | 我想能不能让用户程序能很方便地从裸机程序修改为用户程序, 94 | 即将返回处理命令写在监控程序中, 用户程序只需简单地调用监控程序中的指令, 95 | 我使用了软中断来解决这个问题. 96 | 经查资料, 软中断由中断向量表管理, 实模式下从内存的物理地址0x00000开始, 97 | 到0x003ff结束. 将中断程序的偏移地址和段地址写入对应内存即可. 98 | 我在监控程序写了20h和21h中断, 将它们加入中断向量表中. 99 | 这样, 用户程序只需简单修改就可以与监控程序良好地切换了. 100 | 在设计过程中, 我也遇到了一些小问题, 比如用错寄存器, 101 | 没有注意到一个变量修改后会影响到其它区域, 需要用栈保护一些寄存器, 102 | 调试了很久才发现错误发生在其它位置. 103 | 我觉得汇编中, 尤其要知道寄存器的值在什么时候, 哪个例程中会被改变. 104 | 我也思考了多任务系统的实现方式, 也查找了相关资料. 我的想法是: 105 | 将多个程序读入不同的内存位置, 每个程序的起始位置用于保存各个寄存器, 106 | 当前执行的指令位置. 然后在每个用户程序中调用一个中断, 返回监控程序后, 107 | 存储当前寄存器状态, 108 | 让监控程序执行另一个用户程序, 这样不断交替执行. 109 | 我遇到的问题是, 由于用户程序的起始点不一致, 110 | 而且用户程序无法预知其被写入的内存地址, 如何设置用户程序中的段地址. 111 | 这个问题我将会在之后尝试解决. 112 | -------------------------------------------------------------------------------- /lab2/wkcn.asm: -------------------------------------------------------------------------------- 1 | ;Running Ball 2 | ;Jackie Wu (Wu Kan) 3 | ;14348134 4 | ;wkcn@live.cn 5 | 6 | ;totalDelay = outDelay * inDelay 7 | org 0A100H 8 | outDelay equ 50000 9 | inDelay equ 1800 10 | 11 | ;80 x 25 12 | MIN_X equ 10 13 | MIN_Y equ 10 14 | MAX_X equ 80 15 | MAX_Y equ 25 16 | 17 | ;set data segment 18 | ;mov ax,07c0h 19 | mov ax,cs 20 | mov ds,ax 21 | 22 | ;text window 23 | ;25 * 80 24 | mov ax,0B800h 25 | mov es,ax 26 | 27 | 28 | %macro SINGLE 4 29 | ;pos dw 0000h ;from 0,0 30 | ;vel dw 0101h ;v = (1,1) 31 | ;char db '*' 32 | ;color db 07H 33 | 34 | mov ax, [%1] 35 | mov [pos], ax 36 | mov ax, [%2] 37 | mov [vel], ax 38 | mov al, [%3] 39 | mov [char], al 40 | mov al, [%4] 41 | mov [color], al 42 | 43 | call PLAY 44 | 45 | mov ax, [pos] 46 | mov [%1], ax 47 | mov ax, [vel] 48 | mov [%2], ax 49 | %endmacro 50 | 51 | START: 52 | call DELAY 53 | call PLAY 54 | SINGLE pos1,vel1,char1,color1 55 | SINGLE pos2,vel2,char2,color2 56 | SINGLE pos3,vel3,char3,color3 57 | call SHOWNAME 58 | int 20h 59 | jmp START 60 | 61 | PLAY: 62 | call SETPOINTER 63 | call ELIMINATE 64 | 65 | call UPDATEPOS 66 | 67 | call SETPOINTER 68 | call SHOW 69 | ret 70 | 71 | SHOWNAME: 72 | mov cx,[msgLen] 73 | 74 | mov si,message 75 | 76 | mov di, 12*80 + 50 77 | 78 | mov dl,[msgColor] 79 | 80 | printChar: 81 | mov al,[si] 82 | inc si 83 | mov ah,dl 84 | add dl,1 85 | mov [es:di],ax 86 | add di,2 87 | loop printChar 88 | 89 | inc byte[msgColor] 90 | 91 | ret 92 | 93 | DELAY: 94 | mov cx, outDelay 95 | LOOP1: 96 | mov ax, inDelay 97 | LOOP2: 98 | dec ax 99 | jg LOOP2 100 | loop LOOP1 101 | 102 | ret 103 | 104 | UPDATEPOS: 105 | ;parameter: pos, vel 106 | mov ax,[pos] 107 | mov bx,[vel] 108 | 109 | ;update x 110 | add ah,bh 111 | cmp ah,MIN_X 112 | jne XNZ 113 | ;if x == MIN_X 114 | mov bh,1 115 | XNZ: 116 | CMP ah,MAX_X-1 117 | jl XNF 118 | ;if x >= MAX_X-1 119 | mov bh,-1 120 | XNF: 121 | ;update y 122 | add al,bl 123 | cmp al,MIN_Y 124 | jne YNZ 125 | ;if y == MIN_Y 126 | mov bl,1 127 | YNZ: 128 | CMP al,MAX_Y-1 129 | jl YNF 130 | ;if y >= MAX_Y-1 131 | mov bl,-1 132 | YNF: 133 | mov [pos],ax 134 | mov [vel],bx 135 | ret 136 | 137 | SETPOINTER: 138 | ;parameter pos, char 139 | mov ax, 0 140 | mov bx, [pos] ; bx = (x,y) 141 | mov al, bl 142 | mov cx, MAX_X 143 | mul cx ; ax *= MAX_X namely ax = y * MAX_X 144 | mov cx, 0 145 | mov cl, bh 146 | add ax, cx ; ax += x 147 | mov cx, 2 148 | mul cx 149 | mov bx, ax 150 | ret 151 | 152 | SHOW: 153 | ;new 154 | mov al, [char] 155 | mov ah, [color] 156 | mov [es:bx],ax 157 | ret 158 | 159 | ELIMINATE: 160 | ;clean 161 | mov ax, 0 162 | mov [es:bx],ax 163 | ret 164 | 165 | 166 | 167 | 168 | DATA: 169 | message db 'WuKan 14348134' 170 | msgLen dw $-message 171 | msgColor db 00h 172 | 173 | outCount dw outDelay 174 | inCount dw inDelay 175 | 176 | pos dw 0000h ;from 0,0 177 | vel dw 0101h ;v = (1,1) 178 | char db '*' 179 | color db 07H 180 | 181 | ;elements 182 | pos1 dw 0000h 183 | vel1 dw 0101h 184 | char1 db '*' 185 | color1 db 03H ;green 186 | 187 | pos2 dw 1010h 188 | vel2 dw 01FFh 189 | char2 db 'A' 190 | color2 db 0CFH ;twinkle red and light white 191 | 192 | pos3 dw 2019h 193 | vel3 dw 0FFFFh 194 | char3 db '@' 195 | color3 db 0EH ;yello 196 | 197 | times 510-($-$$) db 0 198 | dw 0xaa55 199 | -------------------------------------------------------------------------------- /lab2/操作系统原理实验二.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab2/操作系统原理实验二.docx -------------------------------------------------------------------------------- /lab3/Makefile: -------------------------------------------------------------------------------- 1 | BUILD_DIR = build 2 | IMAGE_NAME=disk.img 3 | CC = g++ 4 | CFLAGS = -Iinclude -c -m16 -march=i386 -masm=intel -nostdlib -ffreestanding -mpreferred-stack-boundary=2 -lgcc -shared 5 | OBJCOPY=objcopy 6 | 7 | AS = nasm 8 | ASFLAGS = 9 | LD = ld 10 | LDFLAGS = -m elf_i386 -N 11 | 12 | QEMU = qemu-system-i386 13 | QEMUFLAGS = -fda 14 | 15 | BOCHS = bochs 16 | BOCHSFLAGS = -q -f bochsrc.bxrc 17 | 18 | all: clean build_dir write_image 19 | 20 | build_dir: 21 | -mkdir $(BUILD_DIR) 22 | 23 | write_image: loader.bin kernel.bin wkcn1.com wkcn2.com wkcn3.com wkcn4.com kan.com 24 | dd if=/dev/zero of=$(BUILD_DIR)/$(IMAGE_NAME) bs=512 count=2880 25 | dd if=$(BUILD_DIR)/loader.bin of=$(BUILD_DIR)/$(IMAGE_NAME) bs=512 count=1 conv=notrunc 26 | dd if=$(BUILD_DIR)/kernel.bin of=$(BUILD_DIR)/$(IMAGE_NAME) bs=512 seek=2 conv=notrunc #Shanqu 3 27 | printf "\x55\xaa" | dd of=$(BUILD_DIR)/$(IMAGE_NAME) bs=1 seek=510 count=2 conv=notrunc 28 | #User Programs 29 | dd if=$(BUILD_DIR)/wkcn1.com of=$(BUILD_DIR)/$(IMAGE_NAME) bs=512 seek=18 conv=notrunc 30 | dd if=$(BUILD_DIR)/wkcn2.com of=$(BUILD_DIR)/$(IMAGE_NAME) bs=512 seek=19 conv=notrunc 31 | dd if=$(BUILD_DIR)/wkcn3.com of=$(BUILD_DIR)/$(IMAGE_NAME) bs=512 seek=20 conv=notrunc 32 | dd if=$(BUILD_DIR)/wkcn4.com of=$(BUILD_DIR)/$(IMAGE_NAME) bs=512 seek=21 conv=notrunc 33 | dd if=$(BUILD_DIR)/kan.com of=$(BUILD_DIR)/$(IMAGE_NAME) bs=512 seek=22 conv=notrunc 34 | 35 | 36 | loader.bin: loader.asm 37 | $(AS) $(ASFLAGS) -f bin $^ -o $(BUILD_DIR)/$@ 38 | 39 | kernel.bin: kernel.o os.o 40 | $(LD) $(LDFLAGS) -Ttext 0x7e00 --oformat binary $(BUILD_DIR)/kernel.o $(BUILD_DIR)/os.o -o $(BUILD_DIR)/$@ 41 | 42 | 43 | %.o: %.c 44 | $(CC) $(CFLAGS) $< -o $(BUILD_DIR)/$@ 45 | %.o: %.cpp 46 | $(CC) $(CFLAGS) $< -o $(BUILD_DIR)/$@ 47 | %.o: %.asm 48 | $(AS) $(ASFLAGS) -f elf32 $^ -o $(BUILD_DIR)/$@ 49 | %.com: %.asm 50 | $(AS) $(ASFLAGS) -f bin $^ -o $(BUILD_DIR)/$@ 51 | #$(LD) $(LDFLAGS) -Ttext 0x0100 $(BUILD_DIR)/$^ -o $(BUILD_DIR)/$@ 52 | 53 | qemu: 54 | $(QEMU) $(QEMUFLAGS) $(BUILD_DIR)/disk.img 55 | 56 | run: qemu 57 | 58 | bochs: 59 | $(BOCHS) $(BOCHSFLAGS) 60 | 61 | clean: 62 | -rm -rf build 63 | -------------------------------------------------------------------------------- /lab3/ReadMe.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab3/ReadMe.txt -------------------------------------------------------------------------------- /lab3/include/defines.h: -------------------------------------------------------------------------------- 1 | #ifndef _DEFINES_H_ 2 | #define _DEFINES_H_ 3 | 4 | #include 5 | 6 | #define SCREEN_WIDTH 80 7 | #define SCREEN_HEIGHT 25 8 | 9 | 10 | const char *NEWLINE = "\r\n"; 11 | 12 | #define STREAM_MAX_LEN 16 13 | struct stream{ 14 | char str[STREAM_MAX_LEN]; 15 | uint16_t len; 16 | void put(char ch){ 17 | if (len+1 < STREAM_MAX_LEN){ 18 | str[len++] = ch; 19 | str[len] = 0; 20 | } 21 | } 22 | void pop(){ 23 | if (len > 0){ 24 | str[--len] = 0; 25 | } 26 | } 27 | stream(){ 28 | len = 0; 29 | } 30 | }; 31 | 32 | //Font Color 33 | enum Color{ 34 | BLACK = 0x00, 35 | BLUE, 36 | GREEN, 37 | CYAN, // 青色 38 | RED, 39 | CARM, // 洋红 40 | BROWN, 41 | WHITE, 42 | GRAY, 43 | LBLUE, 44 | LGREEN, 45 | LCYAN, 46 | LRED, 47 | LCARM, 48 | YELLOW, 49 | LWHITE 50 | }; 51 | 52 | typedef uint16_t osi; // default interger in OS 53 | 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /lab3/include/io.h: -------------------------------------------------------------------------------- 1 | #ifndef _IO_H_ 2 | #define _IO_H_ 3 | 4 | #include "defines.h" 5 | 6 | char getchar(){ 7 | // 获得一个按键(需等待) 8 | char ch; 9 | asm volatile("int 0x16;" 10 | :"=a"(ch) 11 | :"a"(0x1000) 12 | ); 13 | return ch; 14 | } 15 | 16 | osi GetCursor(){ 17 | // H: row 18 | // L column 19 | osi p; 20 | asm volatile("int 0x10;" 21 | :"=d"(p) 22 | :"a"(0x0300),"b"(0) 23 | ); 24 | return p; 25 | } 26 | 27 | __attribute__((regparm(2))) 28 | void SetCursor(osi r, osi c){ 29 | asm volatile("int 0x10;" 30 | : 31 | :"a"(0x0200),"b"(0),"d"((r << 8) | c) 32 | ); 33 | } 34 | 35 | void CLS(){ 36 | /* 37 | AH = 06h to scroll up 38 | = 07h to scroll down 39 | AL = Number of lines to scroll (if zero, entire window is blanked) 40 | BH = Attribute to be used for blanked area 41 | CH = y coordinate, upper left corner of window 42 | CL = x coordinate, upper left corner of window 43 | DH = y coordinate, lower right corner of window 44 | DL = x coordinate, lower right corner of window 45 | */ 46 | asm volatile("int 0x10" 47 | : 48 | :"a"(3) 49 | ); 50 | } 51 | 52 | 53 | 54 | 55 | __attribute__((regparm(3))) 56 | void DrawChar(char ch,osi r,osi c,osi color = 0x07){ 57 | osi k = (r * 80 + c) * 2; 58 | asm volatile( 59 | "push es;" 60 | "mov es, ax;" 61 | "mov es:[bx],cx;" 62 | "pop es;" 63 | : 64 | :"a"(0xB800),"b"(k), "c"((color<<8) | ch) 65 | : 66 | ); 67 | } 68 | 69 | __attribute__((regparm(3))) 70 | void DrawText(const char *str,osi r,osi c,osi color = 0x07){ 71 | while(*str){ 72 | DrawChar(*(str++),r,c++,color); 73 | } 74 | } 75 | 76 | __attribute__((regparm(2))) 77 | void PrintChar(char ch, osi color = 0x07){ 78 | //Use 10h interupt to get right cursor position 79 | osi ocp = GetCursor(); 80 | osi orow = ocp >> 8; 81 | osi ocol = ocp & 0x00FF; 82 | asm volatile("int 0x10;" 83 | : 84 | : "a"(0x0E00 | ch), "b"(color) 85 | ); 86 | //color 87 | if (ch != '\n' && ch != '\b' && ch != '\r'){ 88 | osi cp = GetCursor(); 89 | osi row = cp >> 8; 90 | osi col = cp & 0x00FF; 91 | DrawChar(ch,orow,ocol,color); 92 | SetCursor(row,col); 93 | } 94 | } 95 | 96 | __attribute__((regparm(2))) 97 | void PrintStr(const char *str, osi color = 0x07){ 98 | while(*str){ 99 | PrintChar(*str,color); 100 | ++str; 101 | } 102 | } 103 | 104 | __attribute__((regparm(1))) 105 | void PrintNum(osi num, osi color = WHITE){ 106 | char temp[16]; 107 | if (num < 0){ 108 | PrintChar('-'); 109 | num = -num; 110 | } 111 | int i = 0; 112 | do{ 113 | temp[i] = num % 10; 114 | num /= 10; 115 | ++i; 116 | }while(num > 0); 117 | 118 | for (int j = i - 1;j >= 0;--j){ 119 | PrintChar(temp[j] + '0', color); 120 | } 121 | } 122 | 123 | __attribute__((regparm(1))) 124 | void ReadProgram(osi id){ 125 | //ReadDisk(0x8000,0x100,); 126 | } 127 | /* 128 | __attribute__((regparm(1))) 129 | void PrintNum(uint16_t num){ 130 | char sstr[16]; 131 | uint16_t temp[16]; 132 | osi i = 0; 133 | 134 | do{ 135 | temp[i] = num % 10; 136 | num /= 10; 137 | ++i; 138 | }while(num > 0); 139 | 140 | osi k = 0; 141 | for (osi j = 3;j >= 0;--j){ 142 | sstr[k] = temp[j] + '0'; 143 | ++k; 144 | } 145 | sstr[k] = 0; 146 | return; 147 | PrintStr(sstr); 148 | } 149 | */ 150 | #endif 151 | -------------------------------------------------------------------------------- /lab3/include/string.h: -------------------------------------------------------------------------------- 1 | #ifndef _STRING_H_ 2 | #define _STRING_H_ 3 | 4 | #include "defines.h" 5 | 6 | __attribute__((regparm(1))) 7 | osi strlen(const char *s){ 8 | osi i = 0; 9 | while(*(s++))i++; 10 | return i; 11 | } 12 | 13 | __attribute__((regparm(2))) 14 | int strcmp(const char *astr,const char *bstr){ 15 | // = 0 16 | // < -1 17 | // > 1 18 | while ((*astr) && (*bstr)){ 19 | if (*astr != *bstr){ 20 | if (*astr < *bstr)return -1; 21 | return 1; 22 | } 23 | ++astr; 24 | ++bstr; 25 | } 26 | return (*astr) - (*bstr); 27 | } 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /lab3/kan.asm: -------------------------------------------------------------------------------- 1 | ;My Name 2 | ;Jackie Wu (Wu Kan) 3 | ;14348134 4 | 5 | org 100H 6 | ;org 7c00h 7 | outDelay equ 40000 8 | inDelay equ 500 9 | 10 | ;set data segment 11 | mov ax,cs 12 | mov ds,ax 13 | 14 | ;text window 15 | ;25 * 80 16 | mov ax,0B800h 17 | mov es,ax 18 | 19 | %macro SETMEM 2 20 | mov ax,%2 21 | mov [%1],ax 22 | %endmacro 23 | 24 | START: 25 | call DELAY 26 | call SHOWINFO 27 | call DELAY 28 | 29 | SETMEM pos,1405H 30 | SETMEM vel,0FF01H 31 | mov cx,8 32 | call LINE 33 | 34 | SETMEM pos,1109H 35 | SETMEM vel,0001H 36 | mov cx,14 37 | call LINE 38 | 39 | SETMEM pos,1705H 40 | SETMEM vel,0001H 41 | mov cx,7 42 | call LINE 43 | 44 | SETMEM pos,1705H 45 | SETMEM vel,0100H 46 | mov cx,10 47 | call LINE 48 | 49 | SETMEM vel,0001H 50 | mov cx,7 51 | call LINE 52 | 53 | SETMEM pos,170BH 54 | SETMEM vel,0100H 55 | mov cx,10 56 | call LINE 57 | 58 | SETMEM pos,170DH 59 | SETMEM vel,0001H 60 | mov cx,8 61 | call LINE 62 | 63 | SETMEM pos,1615H 64 | SETMEM vel,0FF01H 65 | mov cx,2 66 | call LINE 67 | 68 | SETMEM pos,1B0DH 69 | SETMEM vel,0001H 70 | mov cx,10 71 | call LINE 72 | 73 | SETMEM pos,1F0DH 74 | SETMEM vel,0001H 75 | mov cx,9 76 | call LINE 77 | 78 | SETMEM vel,0100H 79 | mov cx,4 80 | call LINE 81 | 82 | SETMEM vel,00FFH 83 | mov cx,2 84 | call LINE 85 | 86 | call DELAY 87 | call DELAY 88 | call DELAY 89 | call DELAY 90 | call DELAY 91 | mov ax,3 92 | int 10h 93 | jmp START 94 | 95 | LINE: 96 | ;cx is the len of line 97 | LINELOOP: 98 | call DELAY 99 | call SHOW 100 | call MOVEPOS 101 | loop LINELOOP 102 | ret 103 | 104 | SHOWINFO: 105 | mov cx,[msgLen] 106 | 107 | mov si,message 108 | 109 | mov di, (1*80 + 1) * 2 110 | 111 | printChar: 112 | mov al,[si] 113 | inc si 114 | mov ah,07h 115 | mov [es:di],ax 116 | add di,2 117 | loop printChar 118 | ret 119 | 120 | DELAY: 121 | push cx 122 | mov cx, outDelay 123 | LOOP1: 124 | mov ax, inDelay 125 | LOOP2: 126 | dec ax 127 | jg LOOP2 128 | loop LOOP1 129 | pop cx 130 | 131 | ret 132 | 133 | MOVEPOS: 134 | mov ax,[pos] 135 | mov bx,[vel] 136 | add ah,bh 137 | add al,bl 138 | mov [pos],ax 139 | ret 140 | 141 | SHOW: 142 | push cx 143 | mov bx,[pos] 144 | mov ax,0 145 | mov al,bl 146 | mov dx,80 147 | mul dx 148 | mov dx,0 149 | mov dl,bh 150 | add ax,dx 151 | mov cx,2 152 | mul cx 153 | mov bx, ax 154 | 155 | mov al,[char] 156 | inc al 157 | cmp al,'Z' 158 | jna LESSZ 159 | mov al,'A' 160 | LESSZ: 161 | mov [char],al 162 | mov ah,[color] 163 | and ah,0Fh 164 | inc byte[color] 165 | mov [es:bx],ax 166 | pop cx 167 | ret 168 | 169 | DATA: 170 | message db "My Name is" 171 | msgLen dw $-message 172 | 173 | pos dw 0000h 174 | vel dw 0000h 175 | char db 'a' 176 | color db 09H 177 | 178 | times 510-($-$$) db 0 179 | dw 0xaa55 180 | -------------------------------------------------------------------------------- /lab3/loader.asm: -------------------------------------------------------------------------------- 1 | BITS 16 2 | org 7c00h 3 | OS_SEGMENT equ 0000h 4 | OS_OFFSET equ 7e00h 5 | 6 | Start: 7 | mov ax,cs 8 | mov ds,ax 9 | mov es,ax 10 | 11 | ReadOS: 12 | ;OS OFFSET 13 | mov ax, OS_SEGMENT 14 | mov es, ax 15 | mov bx, OS_OFFSET 16 | mov ah, 2 ; kind of function 17 | mov al, 17 ; read num of shanqu 18 | mov dl, 0 ; floppy 19 | mov dh, 0 ; citou 20 | mov ch, 0 ; zhumian 21 | mov cl, 3 ; start_shanqu 22 | int 13h 23 | 24 | JUMP_TO_OS: 25 | ;push word OS_SEGMENT 26 | ;push word OS_OFFSET 27 | ;retf 28 | 29 | ;Clear Screen 30 | mov ax, 3 31 | int 10h 32 | ;Print OS INFO 33 | mov ax, cs 34 | mov es, ax 35 | mov ax, 1301h 36 | mov bx, 0003h 37 | mov dh, 2 38 | mov dl, 2 39 | mov bp, OS_INFO 40 | mov cx, OS_INFO_LEN 41 | int 10h 42 | ;Check Key 43 | mov ah, 00h 44 | int 16h 45 | ;Enter Kernel 46 | jmp 0:OS_OFFSET 47 | 48 | OS_INFO dw "Welcome to use Mirai OS! Press any key to enter!" 49 | OS_INFO_LEN equ $ - OS_INFO 50 | times 510 - ($ - $$) db 0 51 | db 0x55 52 | db 0xaa 53 | -------------------------------------------------------------------------------- /lab3/pic/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab3/pic/2.png -------------------------------------------------------------------------------- /lab3/pic/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab3/pic/4.png -------------------------------------------------------------------------------- /lab3/report/14348134吴侃lab3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab3/report/14348134吴侃lab3.pdf -------------------------------------------------------------------------------- /lab3/wkcn1.asm: -------------------------------------------------------------------------------- 1 | ;Running Ball 2 | ;Jackie Wu (Wu Kan) 3 | ;14348134 4 | ;wkcn@live.cn 5 | 6 | ;totalDelay = outDelay * inDelay 7 | org 100H 8 | outDelay equ 40000 9 | inDelay equ 1000 10 | 11 | ;80 x 25 12 | SCREEN_X equ 80 13 | SCREEN_Y equ 25 14 | ;Ball in this Rect 15 | MIN_X equ 40 16 | MIN_Y equ 0 17 | MAX_X equ 80 18 | MAX_Y equ 13 19 | 20 | ;set data segment 21 | ;mov ax,07c0h 22 | mov ax,cs 23 | mov ds,ax 24 | 25 | ;text window 26 | ;25 * 80 27 | mov ax,0B800h 28 | mov es,ax 29 | 30 | 31 | %macro SINGLE 4 32 | ;pos dw 0000h ;from 0,0 33 | ;vel dw 0101h ;v = (1,1) 34 | ;char db '*' 35 | ;color db 07H 36 | 37 | mov ax, [%1] 38 | mov [pos], ax 39 | mov ax, [%2] 40 | mov [vel], ax 41 | mov al, [%3] 42 | mov [char], al 43 | mov al, [%4] 44 | mov [color], al 45 | 46 | call PLAY 47 | 48 | mov ax, [pos] 49 | mov [%1], ax 50 | mov ax, [vel] 51 | mov [%2], ax 52 | %endmacro 53 | 54 | START: 55 | call DELAY 56 | ;call PLAY 57 | SINGLE pos1,vel1,char1,color1 58 | SINGLE pos2,vel2,char2,color2 59 | ;SINGLE pos3,vel3,char3,color3 60 | call SHOWNAME 61 | jmp START 62 | 63 | PLAY: 64 | call SETPOINTER 65 | call ELIMINATE 66 | 67 | call UPDATEPOS 68 | 69 | call SETPOINTER 70 | call SHOW 71 | ret 72 | 73 | SHOWNAME: 74 | mov cx,[msgLen] 75 | 76 | mov si,message 77 | 78 | mov di, (1*80 + 1) * 2 79 | 80 | mov dl,[msgColor] 81 | 82 | printChar: 83 | mov al,[si] 84 | inc si 85 | and dl,0Fh 86 | mov ah,dl 87 | add dl,1 88 | mov [es:di],ax 89 | add di,2 90 | loop printChar 91 | 92 | inc byte[msgColor] 93 | 94 | ret 95 | 96 | DELAY: 97 | mov cx, outDelay 98 | LOOP1: 99 | mov ax, inDelay 100 | LOOP2: 101 | dec ax 102 | jg LOOP2 103 | loop LOOP1 104 | 105 | ret 106 | 107 | UPDATEPOS: 108 | ;parameter: pos, vel 109 | mov ax,[pos] 110 | mov bx,[vel] 111 | 112 | ;update x 113 | add ah,bh 114 | cmp ah,MIN_X 115 | ja XNZ 116 | ;if x <= MIN_X 117 | mov bh,1 118 | XNZ: 119 | CMP ah,MAX_X-1 120 | jb XNF 121 | ;if x >= MAX_X-1 122 | mov bh,-1 123 | XNF: 124 | ;update y 125 | add al,bl 126 | cmp al,MIN_Y 127 | ja YNZ 128 | ;if y <= MIN_Y 129 | mov bl,1 130 | YNZ: 131 | CMP al,MAX_Y-1 132 | jb YNF 133 | ;if y >= MAX_Y-1 134 | mov bl,-1 135 | YNF: 136 | mov [pos],ax 137 | mov [vel],bx 138 | ret 139 | 140 | SETPOINTER: 141 | ;parameter pos, char 142 | mov ax, 0 143 | mov bx, [pos] ; bx = (x,y) 144 | mov al, bl 145 | mov cx, SCREEN_X 146 | mul cx ; ax *= SCREEN_X namely ax = y * SCREEN_X 147 | mov cx, 0 148 | mov cl, bh 149 | add ax, cx ; ax += x 150 | mov cx, 2 151 | mul cx 152 | mov bx, ax 153 | ret 154 | 155 | SHOW: 156 | ;new 157 | mov al, [char] 158 | mov ah, [color] 159 | mov [es:bx],ax 160 | ret 161 | 162 | ELIMINATE: 163 | ;clean 164 | mov ax, 0 165 | mov [es:bx],ax 166 | ret 167 | 168 | 169 | 170 | 171 | DATA: 172 | message db "WuKan's Program 1" 173 | msgLen dw $-message 174 | msgColor db 00h 175 | 176 | outCount dw outDelay 177 | inCount dw inDelay 178 | 179 | pos dw 0000h ;from 0,0 180 | vel dw 0101h ;v = (1,1) 181 | char db '*' 182 | color db 03H 183 | 184 | ;elements 185 | pos1 dw 0000h 186 | vel1 dw 0101h 187 | char1 db '*' 188 | color1 db 03H ;green 189 | 190 | pos2 dw 1003h 191 | vel2 dw 01FFh 192 | char2 db 'A' 193 | color2 db 0CFH ;twinkle red and light white 194 | 195 | pos3 dw 2019h 196 | vel3 dw 0FFFFh 197 | char3 db '@' 198 | color3 db 0EH ;yello 199 | 200 | times 510-($-$$) db 0 201 | dw 0xaa55 202 | -------------------------------------------------------------------------------- /lab3/wkcn3.asm: -------------------------------------------------------------------------------- 1 | ;Running Ball 2 | ;Jackie Wu (Wu Kan) 3 | ;14348134 4 | ;wkcn@live.cn 5 | 6 | ;totalDelay = outDelay * inDelay 7 | org 100H 8 | outDelay equ 47000 9 | inDelay equ 1000 10 | 11 | ;80 x 25 12 | SCREEN_X equ 80 13 | SCREEN_Y equ 25 14 | ;Ball in this Rect 15 | MIN_X equ 0 16 | MIN_Y equ 13 17 | MAX_X equ 40 18 | MAX_Y equ 25 19 | 20 | ;set data segment 21 | ;mov ax,07c0h 22 | mov ax,cs 23 | mov ds,ax 24 | 25 | ;text window 26 | ;25 * 80 27 | mov ax,0B800h 28 | mov es,ax 29 | 30 | 31 | %macro SINGLE 4 32 | ;pos dw 0000h ;from 0,0 33 | ;vel dw 0101h ;v = (1,1) 34 | ;char db '*' 35 | ;color db 07H 36 | 37 | mov ax, [%1] 38 | mov [pos], ax 39 | mov ax, [%2] 40 | mov [vel], ax 41 | mov al, [%3] 42 | mov [char], al 43 | mov al, [%4] 44 | mov [color], al 45 | 46 | call PLAY 47 | 48 | mov ax, [pos] 49 | mov [%1], ax 50 | mov ax, [vel] 51 | mov [%2], ax 52 | %endmacro 53 | 54 | START: 55 | call DELAY 56 | ;call PLAY 57 | SINGLE pos1,vel1,char1,color1 58 | SINGLE pos2,vel2,char2,color2 59 | SINGLE pos3,vel3,char3,color3 60 | call SHOWNAME 61 | jmp START 62 | 63 | PLAY: 64 | call SETPOINTER 65 | call ELIMINATE 66 | 67 | call UPDATEPOS 68 | 69 | call SETPOINTER 70 | call SHOW 71 | ret 72 | 73 | SHOWNAME: 74 | mov cx,[msgLen] 75 | 76 | mov si,message 77 | 78 | mov di, (1*80 + 1) * 2 79 | 80 | mov dl,[msgColor] 81 | 82 | printChar: 83 | mov al,[si] 84 | inc si 85 | and dl,0Fh 86 | mov ah,dl 87 | add dl,1 88 | mov [es:di],ax 89 | add di,2 90 | loop printChar 91 | 92 | inc byte[msgColor] 93 | 94 | ret 95 | 96 | DELAY: 97 | mov cx, outDelay 98 | LOOP1: 99 | mov ax, inDelay 100 | LOOP2: 101 | dec ax 102 | jg LOOP2 103 | loop LOOP1 104 | 105 | ret 106 | 107 | UPDATEPOS: 108 | ;parameter: pos, vel 109 | mov ax,[pos] 110 | mov bx,[vel] 111 | 112 | ;update x 113 | add ah,bh 114 | cmp ah,MIN_X 115 | ja XNZ 116 | ;if x <= MIN_X 117 | mov bh,1 118 | XNZ: 119 | CMP ah,MAX_X-1 120 | jb XNF 121 | ;if x >= MAX_X-1 122 | mov bh,-1 123 | XNF: 124 | ;update y 125 | add al,bl 126 | cmp al,MIN_Y 127 | ja YNZ 128 | ;if y <= MIN_Y 129 | mov bl,1 130 | YNZ: 131 | CMP al,MAX_Y-1 132 | jb YNF 133 | ;if y >= MAX_Y-1 134 | mov bl,-1 135 | YNF: 136 | mov [pos],ax 137 | mov [vel],bx 138 | ret 139 | 140 | SETPOINTER: 141 | ;parameter pos, char 142 | mov ax, 0 143 | mov bx, [pos] ; bx = (x,y) 144 | mov al, bl 145 | mov cx, SCREEN_X 146 | mul cx ; ax *= SCREEN_X namely ax = y * SCREEN_X 147 | mov cx, 0 148 | mov cl, bh 149 | add ax, cx ; ax += x 150 | mov cx, 2 151 | mul cx 152 | mov bx, ax 153 | ret 154 | 155 | SHOW: 156 | ;new 157 | mov al, [char] 158 | mov ah, [color] 159 | mov [es:bx],ax 160 | ret 161 | 162 | ELIMINATE: 163 | ;clean 164 | mov ax, 0 165 | mov [es:bx],ax 166 | ret 167 | 168 | 169 | 170 | 171 | DATA: 172 | message db "WuKan's Program 3" 173 | msgLen dw $-message 174 | msgColor db 00h 175 | 176 | outCount dw outDelay 177 | inCount dw inDelay 178 | 179 | pos dw 0000h ;from 0,0 180 | vel dw 0101h ;v = (1,1) 181 | char db '*' 182 | color db 03H 183 | 184 | ;elements 185 | pos1 dw 0000h 186 | vel1 dw 0101h 187 | char1 db '*' 188 | color1 db 03H ;green 189 | 190 | pos2 dw 1003h 191 | vel2 dw 01FFh 192 | char2 db 'A' 193 | color2 db 0CFH ;twinkle red and light white 194 | 195 | pos3 dw 2019h 196 | vel3 dw 0FFFFh 197 | char3 db '@' 198 | color3 db 0EH ;yello 199 | 200 | times 510-($-$$) db 0 201 | dw 0xaa55 202 | -------------------------------------------------------------------------------- /lab4/Makefile: -------------------------------------------------------------------------------- 1 | BUILD_DIR = build 2 | DISK_DIR = disk 3 | KITS_DIR = kits 4 | IMAGE_NAME=disk.img 5 | CC = g++ 6 | CFLAGS = -Iinclude -c -m16 -march=i386 -masm=intel -nostdlib -ffreestanding -mpreferred-stack-boundary=2 -lgcc -shared -std=c++11 -Wno-int-to-void-pointer-cast 7 | 8 | AS = nasm 9 | ASFLAGS = 10 | LD = ld 11 | LDFLAGS = -m elf_i386 -N 12 | 13 | #如果不加-fda, 虽然能读Loader, 但无法读扇区:-( 14 | QEMU = qemu-system-i386 15 | QEMUFLAGS = -fda 16 | 17 | BOCHS = bochs 18 | BOCHSFLAGS = -q -f bochsrc.bxrc 19 | 20 | all: clean build_dir write_image write_knl build_progs 21 | umount $(DISK_DIR)/ 22 | 23 | 24 | build_dir: 25 | -mkdir $(BUILD_DIR) 26 | -mkdir $(DISK_DIR) 27 | 28 | write_image: loadknl.bin 29 | dd if=/dev/zero of=$(BUILD_DIR)/disk.img count=2880 30 | dd if=$(BUILD_DIR)/loadknl.bin of=$(BUILD_DIR)/disk.img conv=notrunc 31 | mount -o loop $(BUILD_DIR)/disk.img disk/ 32 | 33 | write_knl: kernel.bin 34 | cp $(BUILD_DIR)/kernel.bin $(DISK_DIR)/ 35 | 36 | build_progs: wkcn1.com wkcn2.com wkcn3.com wkcn4.com kan.com hello.com bs.com bpb.com ls.com 37 | for name in $^; do\ 38 | cp $(BUILD_DIR)/$$name $(DISK_DIR)/;\ 39 | done 40 | 41 | loadknl.bin: loadknl.asm 42 | $(AS) $(ASFLAGS) -f bin $^ -o $(BUILD_DIR)/$@ 43 | 44 | kernel.bin: kernel.o os.o 45 | $(LD) $(LDFLAGS) -Ttext 0x7e00 --oformat binary $(BUILD_DIR)/kernel.o $(BUILD_DIR)/os.o -o $(BUILD_DIR)/$@ 46 | 47 | 48 | %.o: %.c 49 | $(CC) $(CFLAGS) $< -o $(BUILD_DIR)/$@ 50 | %.o: %.cpp 51 | $(CC) $(CFLAGS) $< -o $(BUILD_DIR)/$@ 52 | %.o: %.asm 53 | $(AS) $(ASFLAGS) -f elf32 $^ -o $(BUILD_DIR)/$@ 54 | %.com: %.o header.o 55 | #$(LD) $(LDFLAGS) -Ttext 0x100 --oformat binary $(BUILD_DIR)/header.o $(BUILD_DIR)/$< -o $(BUILD_DIR)/$@ 56 | $(LD) $(LDFLAGS) -T linker_100.ld --oformat binary $(BUILD_DIR)/header.o $(BUILD_DIR)/$< -o $(BUILD_DIR)/$@ 57 | %.com: %.asm 58 | $(AS) $(ASFLAGS) -f bin $^ -o $(BUILD_DIR)/$@ 59 | #$(LD) $(LDFLAGS) -Ttext 0x0100 $(BUILD_DIR)/$^ -o $(DISK_DIR)/$@ 60 | 61 | qemu: 62 | $(QEMU) $(QEMUFLAGS) $(BUILD_DIR)/disk.img 63 | 64 | run: qemu 65 | 66 | bochs: 67 | $(BOCHS) $(BOCHSFLAGS) 68 | 69 | clean: 70 | -rm -rf $(BUILD_DIR) 71 | -rm -rf $(DISK_DIR) 72 | -------------------------------------------------------------------------------- /lab4/ReadMe.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab4/ReadMe.txt -------------------------------------------------------------------------------- /lab4/bpb.cpp: -------------------------------------------------------------------------------- 1 | #include "include/io.h" 2 | //#include "include/disk.h" 3 | 4 | #pragma pack (1) // 按1字节对齐 5 | struct FAT12Header{ 6 | dw jmpShort;//BS_jmpBOOT 一个短跳转指令 7 | db nop; 8 | db BS_OEMName[8]; // 厂商名 9 | dw BPB_BytesPerSec; //每扇区字节数(Bytes/Sector) 0x200 10 | db BPB_SecPerClus; //每簇扇区数(Sector/Cluster) 0x1 11 | dw BPB_ResvdSecCnt; //Boot记录占用多少扇区 ox1 12 | db BPB_NumFATs; //共有多少FAT表 0x2 13 | dw BPB_RootEntCnt; //根目录区文件最大数 0xE0 14 | dw BPB_TotSec16; //扇区总数 0xB40[2*80*18] 15 | db BPB_Media; //介质描述符 0xF0 16 | dw BPB_FATSz16; //每个FAT表所占扇区数 0x9 17 | dw BPB_SecPerTrk; //每磁道扇区数(Sector/track) 0x12 18 | dw BPB_NumHeads; //磁头数(面数) 0x2 19 | dd BPB_HiddSec; //隐藏扇区数 0 20 | dd BPB_TotSec32; //如果BPB_TotSec16=0,则由这里给出扇区数 0 21 | db BS_DrvNum; //INT 13H的驱动器号 0 22 | db BS_Reserved1; //保留,未使用 0 23 | db BS_BootSig; //扩展引导标记(29h) 0x29 24 | dd BS_VolID; //卷序列号 0 25 | db BS_VolLab[11]; //卷标 'wkcn' 26 | db BS_FileSysType[8]; //文件系统类型 'FAT12' 27 | db other[448]; //引导代码及其他数据 引导代码(剩余空间用0填充) 28 | dw _55aa; //第510字节为0x55,第511字节为0xAA 0xAA55 29 | }; 30 | 31 | 32 | __attribute__((regparm(3))) 33 | void ReadFloppy(uint16_t sectorID, uint8_t sectorNum, char *data){ 34 | const uint16_t SecPerTrk = 18; 35 | //const uint16_t BytsPerSec = 512; 36 | uint8_t y = sectorID / SecPerTrk; 37 | uint8_t z = sectorID % SecPerTrk; 38 | uint8_t cl = z + 1; // 起始扇区号 39 | uint8_t ch = y >> 1; // 柱面号 40 | uint8_t dh = y & 1; // 磁头号 41 | uint8_t dl = 0; // 驱动器号, 0表示软盘A 42 | uint8_t ah = 2; // 功能号 43 | uint8_t al = sectorNum; // 读扇区数 44 | asm volatile( 45 | "push es;" 46 | "push ax;" 47 | "mov ax, ds;" 48 | "mov es, ax;" 49 | "pop ax;" 50 | "int 0x13;" 51 | "pop es;" 52 | : 53 | :"a"((ah<<8)|al),"b"(data),"c"((ch<<8)|cl),"d"((dh<<8)|dl) 54 | ); 55 | } 56 | 57 | 58 | FAT12Header header; 59 | int main(){ 60 | ReadFloppy(0,1,(char*)&header); 61 | 62 | PrintStr("jmpShort dw 0x"); 63 | PrintHex((header.jmpShort >> 8) & 0xFF); 64 | PrintHex((header.jmpShort) & 0xFF); 65 | PrintStr(NEWLINE); 66 | PrintStr("nop"); 67 | PrintStr(NEWLINE); 68 | PrintStr("OEMName db \""); 69 | PrintStrN(header.BS_OEMName,8); 70 | PrintChar('\"'); 71 | PrintStr(NEWLINE); 72 | 73 | PrintStr("BytesPerSec dw "); 74 | PrintNum(header.BPB_BytesPerSec); 75 | PrintStr(NEWLINE); 76 | 77 | PrintStr("SecPerClus db "); 78 | PrintNum(header.BPB_SecPerClus); 79 | PrintStr(NEWLINE); 80 | 81 | PrintStr("ResvdSecCnt dw "); 82 | PrintNum(header.BPB_ResvdSecCnt); 83 | PrintStr(NEWLINE); 84 | 85 | PrintStr("NumFATs db "); 86 | PrintNum(header.BPB_NumFATs); 87 | PrintStr(NEWLINE); 88 | 89 | PrintStr("RootEntCnt dw "); 90 | PrintNum(header.BPB_RootEntCnt); 91 | PrintStr(NEWLINE); 92 | 93 | PrintStr("TotSec16 dw "); 94 | PrintNum(header.BPB_TotSec16); 95 | PrintStr(NEWLINE); 96 | 97 | PrintStr("Media db 0x"); 98 | PrintHex(header.BPB_Media); 99 | PrintStr(NEWLINE); 100 | 101 | PrintStr("FatSz16 dw "); 102 | PrintNum(header.BPB_FATSz16); 103 | PrintStr(NEWLINE); 104 | 105 | PrintStr("SecPerTrk dw "); 106 | PrintNum(header.BPB_SecPerTrk); 107 | PrintStr(NEWLINE); 108 | 109 | PrintStr("NumHeads dw "); 110 | PrintNum(header.BPB_NumHeads); 111 | PrintStr(NEWLINE); 112 | 113 | PrintStr("HiddSec dd 0x"); 114 | PrintNum(header.BPB_HiddSec); 115 | PrintStr(NEWLINE); 116 | 117 | PrintStr("TotSec32 dd 0x"); 118 | PrintNum(header.BPB_TotSec32); 119 | PrintStr(NEWLINE); 120 | 121 | return 0; 122 | } 123 | -------------------------------------------------------------------------------- /lab4/bs.cpp: -------------------------------------------------------------------------------- 1 | #include "include/io.h" 2 | #include "include/disk.h" 3 | 4 | FAT12Header header; 5 | int main(){ 6 | 7 | ReadFloppy(0,1,&header); 8 | 9 | PrintStr("DrvNum db "); 10 | PrintNum(header.BS_DrvNum); 11 | PrintStr(NEWLINE); 12 | 13 | PrintStr("Reserved1 db "); 14 | PrintNum(header.BS_Reserved1); 15 | PrintStr(NEWLINE); 16 | 17 | PrintStr("BootSig db 0x"); 18 | PrintHex(header.BS_BootSig); 19 | PrintStr(NEWLINE); 20 | 21 | PrintStr("VolID db "); 22 | PrintNum(header.BS_VolID); 23 | PrintStr(NEWLINE); 24 | 25 | PrintStr("VolLab db \""); 26 | PrintStrN(header.BS_VolLab,11); 27 | PrintChar('\"'); 28 | PrintStr(NEWLINE); 29 | 30 | PrintStr("FileSysType db \""); 31 | PrintStrN(header.BS_FileSysType,8); 32 | PrintChar('\"'); 33 | PrintStr(NEWLINE); 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /lab4/header.asm: -------------------------------------------------------------------------------- 1 | BITS 16 2 | 3 | [global _start] 4 | [extern main] 5 | 6 | _start: 7 | ;mov ax, cs 8 | ;mov ds, ax 9 | ;mov ss, ax 10 | ;mov sp, 100h - 4 11 | call main 12 | ;发送程序结束信号,返回Shell 13 | int 20h 14 | ;mov ax, 0x00 15 | ;mov es, ax 16 | ;mov ax, 0x7c00 17 | ;mov si, ax 18 | ;mov ax, 1 19 | ;mov [es:si], ax 20 | jmp $ 21 | -------------------------------------------------------------------------------- /lab4/hello.cpp: -------------------------------------------------------------------------------- 1 | #include "include/io.h" 2 | 3 | int main(){ 4 | PrintStr("Hello, Mirai OS!"); 5 | PrintStr(NEWLINE); 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /lab4/include/defines.h: -------------------------------------------------------------------------------- 1 | #ifndef _DEFINES_H_ 2 | #define _DEFINES_H_ 3 | 4 | #include 5 | 6 | #define SCREEN_WIDTH 80 7 | #define SCREEN_HEIGHT 25 8 | 9 | 10 | const char *NEWLINE = "\r\n"; 11 | 12 | #define STREAM_MAX_LEN 16 13 | struct stream{ 14 | char str[STREAM_MAX_LEN]; 15 | uint16_t len; 16 | void put(char ch){ 17 | if (len+1 < STREAM_MAX_LEN){ 18 | str[len++] = ch; 19 | str[len] = 0; 20 | } 21 | } 22 | void pop(){ 23 | if (len > 0){ 24 | str[--len] = 0; 25 | } 26 | } 27 | stream(){ 28 | len = 0; 29 | } 30 | }; 31 | 32 | //Font Color 33 | enum Color{ 34 | BLACK = 0x00, 35 | BLUE, 36 | GREEN, 37 | CYAN, // 青色 38 | RED, 39 | CARM, // 洋红 40 | BROWN, 41 | WHITE, 42 | GRAY, 43 | LBLUE, 44 | LGREEN, 45 | LCYAN, 46 | LRED, 47 | LCARM, 48 | YELLOW, 49 | LWHITE 50 | }; 51 | 52 | void memcpy(void *dest,void *src,int size){ 53 | for (int i = 0;i < size;++i){ 54 | *(((char*)dest)+i) = *(((char*)src)+i); 55 | } 56 | } 57 | 58 | typedef uint16_t osi; // default interger in OS 59 | 60 | typedef char db; 61 | typedef uint16_t dw; 62 | typedef uint32_t dd; 63 | typedef uint64_t dq; 64 | 65 | extern "C" uint16_t GetKey(); 66 | extern "C" void memcpy(void *dest,const void *src,uint16_t n); 67 | 68 | #define max(a,b) ((a)>(b)?(a):(b)) 69 | #define min(a,b) ((a)<(b)?(a):(b)) 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /lab4/include/string.h: -------------------------------------------------------------------------------- 1 | #ifndef _STRING_H_ 2 | #define _STRING_H_ 3 | 4 | #include "defines.h" 5 | 6 | __attribute__((regparm(1))) 7 | osi strlen(const char *s){ 8 | osi i = 0; 9 | while(*(s++))i++; 10 | return i; 11 | } 12 | 13 | __attribute__((regparm(2))) 14 | int strcmp(const char *astr,const char *bstr){ 15 | // = 0 16 | // < -1 17 | // > 1 18 | while ((*astr) && (*bstr)){ 19 | if (*astr != *bstr){ 20 | if (*astr < *bstr)return -1; 21 | return 1; 22 | } 23 | ++astr; 24 | ++bstr; 25 | } 26 | return (*astr) - (*bstr); 27 | } 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /lab4/kan.asm: -------------------------------------------------------------------------------- 1 | ;My Name 2 | ;Jackie Wu (Wu Kan) 3 | ;14348134 4 | 5 | org 100H 6 | ;org 7c00h 7 | outDelay equ 40000 8 | inDelay equ 500 9 | 10 | ;set data segment 11 | mov ax,cs 12 | mov ds,ax 13 | 14 | ;text window 15 | ;25 * 80 16 | mov ax,0B800h 17 | mov es,ax 18 | 19 | %macro SETMEM 2 20 | mov ax,%2 21 | mov [%1],ax 22 | %endmacro 23 | 24 | START: 25 | call DELAY 26 | call SHOWINFO 27 | call DELAY 28 | 29 | SETMEM pos,1405H 30 | SETMEM vel,0FF01H 31 | mov cx,8 32 | call LINE 33 | 34 | SETMEM pos,1109H 35 | SETMEM vel,0001H 36 | mov cx,14 37 | call LINE 38 | 39 | SETMEM pos,1705H 40 | SETMEM vel,0001H 41 | mov cx,7 42 | call LINE 43 | 44 | SETMEM pos,1705H 45 | SETMEM vel,0100H 46 | mov cx,10 47 | call LINE 48 | 49 | SETMEM vel,0001H 50 | mov cx,7 51 | call LINE 52 | 53 | SETMEM pos,170BH 54 | SETMEM vel,0100H 55 | mov cx,10 56 | call LINE 57 | 58 | SETMEM pos,170DH 59 | SETMEM vel,0001H 60 | mov cx,8 61 | call LINE 62 | 63 | SETMEM pos,1615H 64 | SETMEM vel,0FF01H 65 | mov cx,2 66 | call LINE 67 | 68 | SETMEM pos,1B0DH 69 | SETMEM vel,0001H 70 | mov cx,10 71 | call LINE 72 | 73 | SETMEM pos,1F0DH 74 | SETMEM vel,0001H 75 | mov cx,9 76 | call LINE 77 | 78 | SETMEM vel,0100H 79 | mov cx,4 80 | call LINE 81 | 82 | SETMEM vel,00FFH 83 | mov cx,2 84 | call LINE 85 | 86 | call DELAY 87 | call DELAY 88 | call DELAY 89 | call DELAY 90 | call DELAY 91 | mov ax,3 92 | int 10h 93 | jmp START 94 | 95 | LINE: 96 | ;cx is the len of line 97 | LINELOOP: 98 | call DELAY 99 | call SHOW 100 | call MOVEPOS 101 | loop LINELOOP 102 | ret 103 | 104 | SHOWINFO: 105 | mov cx,[msgLen] 106 | 107 | mov si,message 108 | 109 | mov di, (1*80 + 1) * 2 110 | 111 | printChar: 112 | mov al,[si] 113 | inc si 114 | mov ah,07h 115 | mov [es:di],ax 116 | add di,2 117 | loop printChar 118 | ret 119 | 120 | DELAY: 121 | push cx 122 | mov cx, outDelay 123 | LOOP1: 124 | mov ax, inDelay 125 | LOOP2: 126 | dec ax 127 | jg LOOP2 128 | loop LOOP1 129 | pop cx 130 | 131 | ret 132 | 133 | MOVEPOS: 134 | mov ax,[pos] 135 | mov bx,[vel] 136 | add ah,bh 137 | add al,bl 138 | mov [pos],ax 139 | ret 140 | 141 | SHOW: 142 | push cx 143 | mov bx,[pos] 144 | mov ax,0 145 | mov al,bl 146 | mov dx,80 147 | mul dx 148 | mov dx,0 149 | mov dl,bh 150 | add ax,dx 151 | mov cx,2 152 | mul cx 153 | mov bx, ax 154 | 155 | mov al,[char] 156 | inc al 157 | cmp al,'Z' 158 | jna LESSZ 159 | mov al,'A' 160 | LESSZ: 161 | mov [char],al 162 | mov ah,[color] 163 | and ah,0Fh 164 | inc byte[color] 165 | mov [es:bx],ax 166 | pop cx 167 | ret 168 | 169 | DATA: 170 | message db "My Name is" 171 | msgLen dw $-message 172 | 173 | pos dw 0000h 174 | vel dw 0000h 175 | char db 'a' 176 | color db 09H 177 | 178 | times 510-($-$$) db 0 179 | dw 0xaa55 180 | -------------------------------------------------------------------------------- /lab4/linker_100.ld: -------------------------------------------------------------------------------- 1 | ENTRY(main); 2 | SECTIONS 3 | { 4 | . = 0x100; 5 | .text : AT(0x100) 6 | { 7 | _text = .; 8 | *(.text); 9 | _text_end = .; 10 | } 11 | .data : 12 | { 13 | _data = .; 14 | *(.bss); 15 | *(.bss*); 16 | *(.data); 17 | *(.rodata*); 18 | *(COMMON) 19 | _data_end = .; 20 | } 21 | /DISCARD/ : 22 | { 23 | *(.note*); 24 | *(.iplt*); 25 | *(.igot*); 26 | *(.rel*); 27 | *(.comment); 28 | /* add any unwanted sections spewed out by your version of gcc and flags here */ 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /lab4/ls.cpp: -------------------------------------------------------------------------------- 1 | #include "include/io.h" 2 | #include "include/disk.h" 3 | 4 | char buf[512]; 5 | Entry e; 6 | 7 | const char Months[12][4] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}; 8 | 9 | __attribute__((regparm(1))) 10 | void PrintDate(uint16_t date){ 11 | //Month 12 | uint8_t month = (date >> 5) & 0xF; 13 | PrintStr(Months[month - 1]); 14 | PrintChar('.'); 15 | uint8_t day = (date) & 0x1F; 16 | PrintNum(day); 17 | PrintChar(','); 18 | uint16_t year = uint16_t((date >> 9) & 0x7F) + 1980; 19 | PrintNum(year); 20 | } 21 | 22 | __attribute__((regparm(1))) 23 | void Print2Num(int num){ 24 | PrintChar(num / 10 + '0'); 25 | PrintChar(num % 10 + '0'); 26 | } 27 | 28 | __attribute__((regparm(2))) 29 | void PrintTime(uint16_t t,uint8_t offset){ 30 | uint8_t second = (t & 0x1F) * 2; 31 | uint8_t minute = ((t>>5) & 0x3F); 32 | uint8_t hour = (((t>>11) & 0x1F) + offset)%24; 33 | Print2Num(hour); 34 | PrintChar(':'); 35 | Print2Num(minute); 36 | PrintChar(':'); 37 | Print2Num(second); 38 | } 39 | 40 | char dbuf[1024]; 41 | __attribute__((regparm(1))) 42 | uint16_t GetNextCluster(uint16_t u){ 43 | //get fat 44 | int t = u * 3 / 2; 45 | int p = t / 512; 46 | int o = t % 512; 47 | ReadFloppy(1 + p,2,dbuf); 48 | //uint16_t w = ((buf[o+1]&0xFF) << 8) | (buf[o]&0xFF); 49 | //注意位扩展:-( 50 | uint16_t w = *(uint16_t*)(dbuf + o); 51 | if (u % 2 == 0){ 52 | w &= 0xFFF; 53 | }else{ 54 | w = (w >> 4) & 0xFFF; 55 | } 56 | return w; 57 | } 58 | 59 | __attribute__((regparm(1))) 60 | void PrintClusters(uint16_t u){ 61 | PrintNum(u); 62 | u = GetNextCluster(u); 63 | for(int i = 0;i < 5 &&(!(u >= 0xFF8));++i){ 64 | PrintChar(','); 65 | PrintNum(u); 66 | u = GetNextCluster(u); 67 | } 68 | if (!(u >= 0xFF8)){ 69 | PrintStr(",..."); 70 | } 71 | } 72 | int main(){ 73 | 74 | bool first = true; 75 | for (int i = 19;i < 19 + 14;++i){ 76 | ReadFloppy(i,1,buf); 77 | for (int j = 0;j < 512/32;++j){ 78 | for (int k = 0;k < 32;++k){ 79 | *(((char*)&e) + k) = buf[k + j*32]; 80 | } 81 | if (e.DIR_Name[10] == 0)continue; 82 | if (first){ 83 | first = false; 84 | PrintStr("Filename Size Date Time(UTC+8) Clusters",LBLUE); 85 | PrintStr(NEWLINE); 86 | } 87 | //Print Name 88 | int count = 0; 89 | for (int i = 0;i < 8;++i){ 90 | if(e.DIR_Name[i] && e.DIR_Name[i] != ' '){ 91 | PrintChar(e.DIR_Name[i]); 92 | ++count; 93 | } 94 | else break; 95 | } 96 | PrintChar('.'); 97 | for (int i = 8;i < 11;++i){ 98 | if(e.DIR_Name[i] && e.DIR_Name[i] != ' '){ 99 | PrintChar(e.DIR_Name[i]); 100 | ++count; 101 | } 102 | else break; 103 | } 104 | for (int i = count;i < 11;++i)PrintChar(' '); 105 | count = PrintNum(e.DIR_FileSize); 106 | for(int i = count;i < 6;++i)PrintChar(' '); 107 | PrintDate(e.LAST_WrtDate); 108 | PrintChar(' '); 109 | //使用东八区时间 110 | PrintTime(e.LAST_WrtTime, 8); 111 | //Print Clusters 112 | PrintStr(" "); 113 | PrintClusters(e.DIR_FstClus); 114 | PrintStr(NEWLINE); 115 | } 116 | } 117 | 118 | return 0; 119 | } 120 | -------------------------------------------------------------------------------- /lab4/pic/bpb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab4/pic/bpb.png -------------------------------------------------------------------------------- /lab4/pic/bs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab4/pic/bs.png -------------------------------------------------------------------------------- /lab4/pic/ls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab4/pic/ls.png -------------------------------------------------------------------------------- /lab4/report/14348134吴侃lab4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab4/report/14348134吴侃lab4.pdf -------------------------------------------------------------------------------- /lab4/tools/key.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | struct K{ 8 | string name; 9 | string smm[4]; 10 | string asc[4]; 11 | }; 12 | 13 | int main(){ 14 | ifstream fin("key.txt"); 15 | string name; 16 | string temp; 17 | 18 | vector ks; 19 | do{ 20 | K k; 21 | fin >> name; 22 | if(fin.eof())break; 23 | for (int i = 0;i < name.size();++i){ 24 | char c = name[i]; 25 | if (c >= 'a' && c <= 'z')c = c - 'a' +'A'; 26 | k.name += c; 27 | } 28 | for (int i = 0;i < 4;++i){ 29 | fin >> k.smm[i]; 30 | fin >> k.asc[i]; 31 | } 32 | ks.push_back(k); 33 | }while(!fin.eof()); 34 | ofstream fout("keyboard.h"); 35 | fout << "#ifndef _KEY_BOARD_H_" << endl; 36 | fout << "#define _KEY_BOARD_H_" << endl << endl; 37 | int o = 0; 38 | for (size_t i = 0;i < ks.size();++i){ 39 | K &k = ks[i]; 40 | string name = "KEY_" + k.name; 41 | fout << "#define " << name << " " << "0x" << k.smm[o] << k.asc[o] << endl; 42 | } 43 | o = 1; 44 | for (size_t i = 0;i < ks.size();++i){ 45 | K &k = ks[i]; 46 | string name = "KEY_SHIFT_" + k.name; 47 | fout << "#define " << name << " " << "0x" << k.smm[o] << k.asc[o] << endl; 48 | } 49 | o = 2; 50 | for (size_t i = 0;i < ks.size();++i){ 51 | K &k = ks[i]; 52 | string name = "KEY_CTRL_" + k.name; 53 | fout << "#define " << name << " " << "0x" << k.smm[o] << k.asc[o] << endl; 54 | } 55 | o = 3; 56 | for (size_t i = 0;i < ks.size();++i){ 57 | K &k = ks[i]; 58 | string name = "KEY_ALT_" + k.name; 59 | fout << "#define " << name << " " << "0x" << k.smm[o] << k.asc[o] << endl; 60 | } 61 | fout << endl << endl << "#endif" << endl; 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /lab4/tools/keybuild: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab4/tools/keybuild -------------------------------------------------------------------------------- /lab4/wkcn1.asm: -------------------------------------------------------------------------------- 1 | ;Running Ball 2 | ;Jackie Wu (Wu Kan) 3 | ;14348134 4 | ;wkcn@live.cn 5 | 6 | ;totalDelay = outDelay * inDelay 7 | org 100H 8 | outDelay equ 40000 9 | inDelay equ 1000 10 | 11 | ;80 x 25 12 | SCREEN_X equ 80 13 | SCREEN_Y equ 25 14 | ;Ball in this Rect 15 | MIN_X equ 40 16 | MIN_Y equ 0 17 | MAX_X equ 80 18 | MAX_Y equ 13 19 | 20 | ;set data segment 21 | ;mov ax,07c0h 22 | mov ax,cs 23 | mov ds,ax 24 | 25 | ;text window 26 | ;25 * 80 27 | mov ax,0B800h 28 | mov es,ax 29 | 30 | 31 | %macro SINGLE 4 32 | ;pos dw 0000h ;from 0,0 33 | ;vel dw 0101h ;v = (1,1) 34 | ;char db '*' 35 | ;color db 07H 36 | 37 | mov ax, [%1] 38 | mov [pos], ax 39 | mov ax, [%2] 40 | mov [vel], ax 41 | mov al, [%3] 42 | mov [char], al 43 | mov al, [%4] 44 | mov [color], al 45 | 46 | call PLAY 47 | 48 | mov ax, [pos] 49 | mov [%1], ax 50 | mov ax, [vel] 51 | mov [%2], ax 52 | %endmacro 53 | 54 | START: 55 | call DELAY 56 | ;call PLAY 57 | SINGLE pos1,vel1,char1,color1 58 | SINGLE pos2,vel2,char2,color2 59 | ;SINGLE pos3,vel3,char3,color3 60 | call SHOWNAME 61 | jmp START 62 | 63 | PLAY: 64 | call SETPOINTER 65 | call ELIMINATE 66 | 67 | call UPDATEPOS 68 | 69 | call SETPOINTER 70 | call SHOW 71 | ret 72 | 73 | SHOWNAME: 74 | mov cx,[msgLen] 75 | 76 | mov si,message 77 | 78 | mov di, (1*80 + 1) * 2 79 | 80 | mov dl,[msgColor] 81 | 82 | printChar: 83 | mov al,[si] 84 | inc si 85 | and dl,0Fh 86 | mov ah,dl 87 | add dl,1 88 | mov [es:di],ax 89 | add di,2 90 | loop printChar 91 | 92 | inc byte[msgColor] 93 | 94 | ret 95 | 96 | DELAY: 97 | mov cx, outDelay 98 | LOOP1: 99 | mov ax, inDelay 100 | LOOP2: 101 | dec ax 102 | jg LOOP2 103 | loop LOOP1 104 | 105 | ret 106 | 107 | UPDATEPOS: 108 | ;parameter: pos, vel 109 | mov ax,[pos] 110 | mov bx,[vel] 111 | 112 | ;update x 113 | add ah,bh 114 | cmp ah,MIN_X 115 | ja XNZ 116 | ;if x <= MIN_X 117 | mov bh,1 118 | XNZ: 119 | CMP ah,MAX_X-1 120 | jb XNF 121 | ;if x >= MAX_X-1 122 | mov bh,-1 123 | XNF: 124 | ;update y 125 | add al,bl 126 | cmp al,MIN_Y 127 | ja YNZ 128 | ;if y <= MIN_Y 129 | mov bl,1 130 | YNZ: 131 | CMP al,MAX_Y-1 132 | jb YNF 133 | ;if y >= MAX_Y-1 134 | mov bl,-1 135 | YNF: 136 | mov [pos],ax 137 | mov [vel],bx 138 | ret 139 | 140 | SETPOINTER: 141 | ;parameter pos, char 142 | mov ax, 0 143 | mov bx, [pos] ; bx = (x,y) 144 | mov al, bl 145 | mov cx, SCREEN_X 146 | mul cx ; ax *= SCREEN_X namely ax = y * SCREEN_X 147 | mov cx, 0 148 | mov cl, bh 149 | add ax, cx ; ax += x 150 | mov cx, 2 151 | mul cx 152 | mov bx, ax 153 | ret 154 | 155 | SHOW: 156 | ;new 157 | mov al, [char] 158 | mov ah, [color] 159 | mov [es:bx],ax 160 | ret 161 | 162 | ELIMINATE: 163 | ;clean 164 | mov ax, 0 165 | mov [es:bx],ax 166 | ret 167 | 168 | 169 | 170 | 171 | DATA: 172 | message db "WuKan's Program 1" 173 | msgLen dw $-message 174 | msgColor db 00h 175 | 176 | outCount dw outDelay 177 | inCount dw inDelay 178 | 179 | pos dw 0000h ;from 0,0 180 | vel dw 0101h ;v = (1,1) 181 | char db '*' 182 | color db 03H 183 | 184 | ;elements 185 | pos1 dw 0000h 186 | vel1 dw 0101h 187 | char1 db '*' 188 | color1 db 03H ;green 189 | 190 | pos2 dw 1003h 191 | vel2 dw 01FFh 192 | char2 db 'A' 193 | color2 db 0CFH ;twinkle red and light white 194 | 195 | pos3 dw 2019h 196 | vel3 dw 0FFFFh 197 | char3 db '@' 198 | color3 db 0EH ;yello 199 | 200 | times 510-($-$$) db 0 201 | dw 0xaa55 202 | -------------------------------------------------------------------------------- /lab4/wkcn3.asm: -------------------------------------------------------------------------------- 1 | ;Running Ball 2 | ;Jackie Wu (Wu Kan) 3 | ;14348134 4 | ;wkcn@live.cn 5 | 6 | ;totalDelay = outDelay * inDelay 7 | org 100H 8 | outDelay equ 47000 9 | inDelay equ 1000 10 | 11 | ;80 x 25 12 | SCREEN_X equ 80 13 | SCREEN_Y equ 25 14 | ;Ball in this Rect 15 | MIN_X equ 0 16 | MIN_Y equ 13 17 | MAX_X equ 40 18 | MAX_Y equ 25 19 | 20 | ;set data segment 21 | ;mov ax,07c0h 22 | mov ax,cs 23 | mov ds,ax 24 | 25 | ;text window 26 | ;25 * 80 27 | mov ax,0B800h 28 | mov es,ax 29 | 30 | 31 | %macro SINGLE 4 32 | ;pos dw 0000h ;from 0,0 33 | ;vel dw 0101h ;v = (1,1) 34 | ;char db '*' 35 | ;color db 07H 36 | 37 | mov ax, [%1] 38 | mov [pos], ax 39 | mov ax, [%2] 40 | mov [vel], ax 41 | mov al, [%3] 42 | mov [char], al 43 | mov al, [%4] 44 | mov [color], al 45 | 46 | call PLAY 47 | 48 | mov ax, [pos] 49 | mov [%1], ax 50 | mov ax, [vel] 51 | mov [%2], ax 52 | %endmacro 53 | 54 | START: 55 | call DELAY 56 | ;call PLAY 57 | SINGLE pos1,vel1,char1,color1 58 | SINGLE pos2,vel2,char2,color2 59 | SINGLE pos3,vel3,char3,color3 60 | call SHOWNAME 61 | jmp START 62 | 63 | PLAY: 64 | call SETPOINTER 65 | call ELIMINATE 66 | 67 | call UPDATEPOS 68 | 69 | call SETPOINTER 70 | call SHOW 71 | ret 72 | 73 | SHOWNAME: 74 | mov cx,[msgLen] 75 | 76 | mov si,message 77 | 78 | mov di, (1*80 + 1) * 2 79 | 80 | mov dl,[msgColor] 81 | 82 | printChar: 83 | mov al,[si] 84 | inc si 85 | and dl,0Fh 86 | mov ah,dl 87 | add dl,1 88 | mov [es:di],ax 89 | add di,2 90 | loop printChar 91 | 92 | inc byte[msgColor] 93 | 94 | ret 95 | 96 | DELAY: 97 | mov cx, outDelay 98 | LOOP1: 99 | mov ax, inDelay 100 | LOOP2: 101 | dec ax 102 | jg LOOP2 103 | loop LOOP1 104 | 105 | ret 106 | 107 | UPDATEPOS: 108 | ;parameter: pos, vel 109 | mov ax,[pos] 110 | mov bx,[vel] 111 | 112 | ;update x 113 | add ah,bh 114 | cmp ah,MIN_X 115 | ja XNZ 116 | ;if x <= MIN_X 117 | mov bh,1 118 | XNZ: 119 | CMP ah,MAX_X-1 120 | jb XNF 121 | ;if x >= MAX_X-1 122 | mov bh,-1 123 | XNF: 124 | ;update y 125 | add al,bl 126 | cmp al,MIN_Y 127 | ja YNZ 128 | ;if y <= MIN_Y 129 | mov bl,1 130 | YNZ: 131 | CMP al,MAX_Y-1 132 | jb YNF 133 | ;if y >= MAX_Y-1 134 | mov bl,-1 135 | YNF: 136 | mov [pos],ax 137 | mov [vel],bx 138 | ret 139 | 140 | SETPOINTER: 141 | ;parameter pos, char 142 | mov ax, 0 143 | mov bx, [pos] ; bx = (x,y) 144 | mov al, bl 145 | mov cx, SCREEN_X 146 | mul cx ; ax *= SCREEN_X namely ax = y * SCREEN_X 147 | mov cx, 0 148 | mov cl, bh 149 | add ax, cx ; ax += x 150 | mov cx, 2 151 | mul cx 152 | mov bx, ax 153 | ret 154 | 155 | SHOW: 156 | ;new 157 | mov al, [char] 158 | mov ah, [color] 159 | mov [es:bx],ax 160 | ret 161 | 162 | ELIMINATE: 163 | ;clean 164 | mov ax, 0 165 | mov [es:bx],ax 166 | ret 167 | 168 | 169 | 170 | 171 | DATA: 172 | message db "WuKan's Program 3" 173 | msgLen dw $-message 174 | msgColor db 00h 175 | 176 | outCount dw outDelay 177 | inCount dw inDelay 178 | 179 | pos dw 0000h ;from 0,0 180 | vel dw 0101h ;v = (1,1) 181 | char db '*' 182 | color db 03H 183 | 184 | ;elements 185 | pos1 dw 0000h 186 | vel1 dw 0101h 187 | char1 db '*' 188 | color1 db 03H ;green 189 | 190 | pos2 dw 1003h 191 | vel2 dw 01FFh 192 | char2 db 'A' 193 | color2 db 0CFH ;twinkle red and light white 194 | 195 | pos3 dw 2019h 196 | vel3 dw 0FFFFh 197 | char3 db '@' 198 | color3 db 0EH ;yello 199 | 200 | times 510-($-$$) db 0 201 | dw 0xaa55 202 | -------------------------------------------------------------------------------- /lab5/Makefile: -------------------------------------------------------------------------------- 1 | BUILD_DIR = build 2 | DISK_DIR = disk 3 | KITS_DIR = kits 4 | IMAGE_NAME=disk.img 5 | CC = g++ 6 | CFLAGS = -Iinclude -c -m16 -march=i386 -masm=intel -nostdlib -ffreestanding -mpreferred-stack-boundary=2 -lgcc -shared -std=c++11 -Wno-int-to-void-pointer-cast -fpermissive 7 | 8 | AS = nasm 9 | ASFLAGS = 10 | LD = ld 11 | LDFLAGS = -m elf_i386 -N 12 | 13 | #如果不加-fda, 虽然能读Loader, 但无法读扇区:-( 14 | QEMU = qemu-system-i386 15 | QEMUFLAGS = -fda 16 | 17 | BOCHS = bochs 18 | BOCHSFLAGS = -q -f bochsrc.bxrc 19 | 20 | all: build_dir counter write_image write_knl build_progs 21 | 22 | 23 | build_dir: 24 | -mkdir $(BUILD_DIR) 25 | -mkdir $(DISK_DIR) 26 | ./counter 27 | 28 | write_image: loadknl.bin 29 | dd if=/dev/zero of=$(BUILD_DIR)/disk.img count=2880 30 | dd if=$(BUILD_DIR)/loadknl.bin of=$(BUILD_DIR)/disk.img conv=notrunc 31 | 32 | write_knl: kernel.bin 33 | mount -o loop $(BUILD_DIR)/disk.img disk/ 34 | cp $(BUILD_DIR)/kernel.bin $(DISK_DIR)/ 35 | umount $(DISK_DIR)/ 36 | 37 | build_progs: wkcn1.com wkcn2.com wkcn3.com wkcn4.com kan.com\ 38 | hello.com bs.com bpb.com ls.com help.com\ 39 | box.com ouch.com clock.com\ 40 | inttest.com porttest.com fork1.com fork2.com alpha.com 41 | 42 | mount -o loop $(BUILD_DIR)/disk.img disk/ 43 | 44 | for name in $^; do\ 45 | cp $(BUILD_DIR)/$$name $(DISK_DIR)/;\ 46 | done 47 | 48 | umount $(DISK_DIR)/ 49 | 50 | loadknl.bin: loadknl.asm 51 | $(AS) $(ASFLAGS) -f bin $^ -o $(BUILD_DIR)/$@ 52 | 53 | kernel.bin: kernel.o os.o 54 | $(LD) $(LDFLAGS) -Ttext 0x7e00 --oformat binary $(BUILD_DIR)/kernel.o $(BUILD_DIR)/os.o -o $(BUILD_DIR)/$@ 55 | 56 | 57 | %.o: %.c 58 | $(CC) $(CFLAGS) $< -o $(BUILD_DIR)/$@ 59 | %.o: %.cpp 60 | $(CC) $(CFLAGS) $< -o $(BUILD_DIR)/$@ 61 | %.o: %.asm 62 | $(AS) $(ASFLAGS) -f elf32 $^ -o $(BUILD_DIR)/$@ 63 | %.com: %.o header.o 64 | #$(LD) $(LDFLAGS) -Ttext 0x100 --oformat binary $(BUILD_DIR)/header.o $(BUILD_DIR)/$< -o $(BUILD_DIR)/$@ 65 | $(LD) $(LDFLAGS) -T linker_100.ld --oformat binary $(BUILD_DIR)/header.o $(BUILD_DIR)/$< -o $(BUILD_DIR)/$@ 66 | %.com: %.asm 67 | $(AS) $(ASFLAGS) -f bin $^ -o $(BUILD_DIR)/$@ 68 | #$(LD) $(LDFLAGS) -Ttext 0x0100 $(BUILD_DIR)/$^ -o $(DISK_DIR)/$@ 69 | 70 | qemu: 71 | $(QEMU) $(QEMUFLAGS) $(BUILD_DIR)/disk.img 72 | 73 | run: qemu 74 | 75 | bochs: 76 | $(BOCHS) $(BOCHSFLAGS) 77 | 78 | build_counter: 79 | g++ counter.cpp -o counter 80 | 81 | clean: 82 | -rm -rf $(BUILD_DIR) 83 | -rm -rf $(DISK_DIR) 84 | -------------------------------------------------------------------------------- /lab5/ReadMe.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab5/ReadMe.txt -------------------------------------------------------------------------------- /lab5/alpha.cpp: -------------------------------------------------------------------------------- 1 | #include "include/task.h" 2 | #include "include/io.h" 3 | 4 | char str[64] = "WhAlE aNd MoBuLA"; 5 | int main(){ 6 | PrintStr(str,LBLUE); 7 | PrintStr(NEWLINE); 8 | if (fork()){ 9 | //大写 10 | asm volatile( 11 | "mov dx,cs;" 12 | "int 0x24;" 13 | : 14 | :"a"(0x0100),"b"(str) 15 | :"dx" 16 | ); 17 | PrintStr(str,RED); 18 | }else{ 19 | //小写 20 | asm volatile( 21 | "mov dx,cs;" 22 | "int 0x24;" 23 | : 24 | :"a"(0x0000),"b"(str) 25 | :"dx" 26 | ); 27 | PrintStr(str,LGREEN); 28 | } 29 | PrintStr(NEWLINE); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /lab5/bpb.cpp: -------------------------------------------------------------------------------- 1 | #include "include/io.h" 2 | //#include "include/disk.h" 3 | 4 | #pragma pack (1) // 按1字节对齐 5 | struct FAT12Header{ 6 | dw jmpShort;//BS_jmpBOOT 一个短跳转指令 7 | db nop; 8 | db BS_OEMName[8]; // 厂商名 9 | dw BPB_BytesPerSec; //每扇区字节数(Bytes/Sector) 0x200 10 | db BPB_SecPerClus; //每簇扇区数(Sector/Cluster) 0x1 11 | dw BPB_ResvdSecCnt; //Boot记录占用多少扇区 ox1 12 | db BPB_NumFATs; //共有多少FAT表 0x2 13 | dw BPB_RootEntCnt; //根目录区文件最大数 0xE0 14 | dw BPB_TotSec16; //扇区总数 0xB40[2*80*18] 15 | db BPB_Media; //介质描述符 0xF0 16 | dw BPB_FATSz16; //每个FAT表所占扇区数 0x9 17 | dw BPB_SecPerTrk; //每磁道扇区数(Sector/track) 0x12 18 | dw BPB_NumHeads; //磁头数(面数) 0x2 19 | dd BPB_HiddSec; //隐藏扇区数 0 20 | dd BPB_TotSec32; //如果BPB_TotSec16=0,则由这里给出扇区数 0 21 | db BS_DrvNum; //INT 13H的驱动器号 0 22 | db BS_Reserved1; //保留,未使用 0 23 | db BS_BootSig; //扩展引导标记(29h) 0x29 24 | dd BS_VolID; //卷序列号 0 25 | db BS_VolLab[11]; //卷标 'wkcn' 26 | db BS_FileSysType[8]; //文件系统类型 'FAT12' 27 | db other[448]; //引导代码及其他数据 引导代码(剩余空间用0填充) 28 | dw _55aa; //第510字节为0x55,第511字节为0xAA 0xAA55 29 | }; 30 | 31 | 32 | __attribute__((regparm(3))) 33 | void ReadFloppy(uint16_t sectorID, uint8_t sectorNum, char *data){ 34 | const uint16_t SecPerTrk = 18; 35 | //const uint16_t BytsPerSec = 512; 36 | uint8_t y = sectorID / SecPerTrk; 37 | uint8_t z = sectorID % SecPerTrk; 38 | uint8_t cl = z + 1; // 起始扇区号 39 | uint8_t ch = y >> 1; // 柱面号 40 | uint8_t dh = y & 1; // 磁头号 41 | uint8_t dl = 0; // 驱动器号, 0表示软盘A 42 | uint8_t ah = 2; // 功能号 43 | uint8_t al = sectorNum; // 读扇区数 44 | asm volatile( 45 | "push es;" 46 | "push ax;" 47 | "mov ax, ds;" 48 | "mov es, ax;" 49 | "pop ax;" 50 | "int 0x13;" 51 | "pop es;" 52 | : 53 | :"a"((ah<<8)|al),"b"(data),"c"((ch<<8)|cl),"d"((dh<<8)|dl) 54 | ); 55 | } 56 | 57 | 58 | FAT12Header header; 59 | int main(){ 60 | ReadFloppy(0,1,(char*)&header); 61 | 62 | PrintStr("jmpShort dw 0x"); 63 | PrintHex((header.jmpShort >> 8) & 0xFF); 64 | PrintHex((header.jmpShort) & 0xFF); 65 | PrintStr(NEWLINE); 66 | PrintStr("nop"); 67 | PrintStr(NEWLINE); 68 | PrintStr("OEMName db \""); 69 | PrintStrN(header.BS_OEMName,8); 70 | PrintChar('\"'); 71 | PrintStr(NEWLINE); 72 | 73 | PrintStr("BytesPerSec dw "); 74 | PrintNum(header.BPB_BytesPerSec); 75 | PrintStr(NEWLINE); 76 | 77 | PrintStr("SecPerClus db "); 78 | PrintNum(header.BPB_SecPerClus); 79 | PrintStr(NEWLINE); 80 | 81 | PrintStr("ResvdSecCnt dw "); 82 | PrintNum(header.BPB_ResvdSecCnt); 83 | PrintStr(NEWLINE); 84 | 85 | PrintStr("NumFATs db "); 86 | PrintNum(header.BPB_NumFATs); 87 | PrintStr(NEWLINE); 88 | 89 | PrintStr("RootEntCnt dw "); 90 | PrintNum(header.BPB_RootEntCnt); 91 | PrintStr(NEWLINE); 92 | 93 | PrintStr("TotSec16 dw "); 94 | PrintNum(header.BPB_TotSec16); 95 | PrintStr(NEWLINE); 96 | 97 | PrintStr("Media db 0x"); 98 | PrintHex(header.BPB_Media); 99 | PrintStr(NEWLINE); 100 | 101 | PrintStr("FatSz16 dw "); 102 | PrintNum(header.BPB_FATSz16); 103 | PrintStr(NEWLINE); 104 | 105 | PrintStr("SecPerTrk dw "); 106 | PrintNum(header.BPB_SecPerTrk); 107 | PrintStr(NEWLINE); 108 | 109 | PrintStr("NumHeads dw "); 110 | PrintNum(header.BPB_NumHeads); 111 | PrintStr(NEWLINE); 112 | 113 | PrintStr("HiddSec dd 0x"); 114 | PrintNum(header.BPB_HiddSec); 115 | PrintStr(NEWLINE); 116 | 117 | PrintStr("TotSec32 dd 0x"); 118 | PrintNum(header.BPB_TotSec32); 119 | PrintStr(NEWLINE); 120 | 121 | return 0; 122 | } 123 | -------------------------------------------------------------------------------- /lab5/bs.cpp: -------------------------------------------------------------------------------- 1 | #include "include/io.h" 2 | #include "include/disk.h" 3 | 4 | FAT12Header header; 5 | int main(){ 6 | 7 | ReadFloppy(0,1,&header); 8 | 9 | PrintStr("DrvNum db "); 10 | PrintNum(header.BS_DrvNum); 11 | PrintStr(NEWLINE); 12 | 13 | PrintStr("Reserved1 db "); 14 | PrintNum(header.BS_Reserved1); 15 | PrintStr(NEWLINE); 16 | 17 | PrintStr("BootSig db 0x"); 18 | PrintHex(header.BS_BootSig); 19 | PrintStr(NEWLINE); 20 | 21 | PrintStr("VolID db "); 22 | PrintNum(header.BS_VolID); 23 | PrintStr(NEWLINE); 24 | 25 | PrintStr("VolLab db \""); 26 | PrintStrN(header.BS_VolLab,11); 27 | PrintChar('\"'); 28 | PrintStr(NEWLINE); 29 | 30 | PrintStr("FileSysType db \""); 31 | PrintStrN(header.BS_FileSysType,8); 32 | PrintChar('\"'); 33 | PrintStr(NEWLINE); 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /lab5/clock.cpp: -------------------------------------------------------------------------------- 1 | #include "include/io.h" 2 | 3 | int main(){ 4 | PrintNum(clock()); 5 | PrintStr(NEWLINE); 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /lab5/counter: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab5/counter -------------------------------------------------------------------------------- /lab5/counter.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | string head = "#define RELEASE_TIMES "; 6 | string filename = "include/version.h"; 7 | int main(){ 8 | fstream fin(filename.c_str()); 9 | fin.seekg(head.size()); 10 | int v; 11 | fin >> v; 12 | ++v; 13 | cout << head << v << endl; 14 | fin.seekp(0,ios::beg); 15 | fin << head << v << endl; 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /lab5/fork1.cpp: -------------------------------------------------------------------------------- 1 | #include "include/io.h" 2 | #include "include/task.h" 3 | 4 | int main(){ 5 | if (fork() == 0){ 6 | for (int i = 0;i < 20;++i){ 7 | PrintChar('.'); 8 | } 9 | }else{ 10 | if (fork() == 0){ 11 | for (int i = 0;i < 20;++i){ 12 | PrintChar('o'); 13 | } 14 | }else{ 15 | for (int i = 0;i < 20;++i){ 16 | PrintChar('x'); 17 | } 18 | } 19 | } 20 | PrintStr(NEWLINE); 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /lab5/fork2.cpp: -------------------------------------------------------------------------------- 1 | #include "include/io.h" 2 | #include "include/task.h" 3 | 4 | ostream cout; 5 | int main(){ 6 | int i=0; 7 | for(i=0;i<3;i++){ 8 | uint8_t fpid=fork(); 9 | if(fpid==0) 10 | PrintStr("son", YELLOW); 11 | else 12 | PrintStr("FATHER",LGREEN); 13 | PrintStr(NEWLINE); 14 | } 15 | return 0; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /lab5/header.asm: -------------------------------------------------------------------------------- 1 | BITS 16 2 | 3 | [global _start] 4 | [extern main] 5 | 6 | _start: 7 | ;mov ax, cs 8 | ;mov ds, ax 9 | ;mov ss, ax 10 | ;mov sp, 100h - 4 11 | call main 12 | ;发送程序结束信号,返回Shell 13 | sti 14 | int 20h 15 | ;mov ax, 0x00 16 | ;mov es, ax 17 | ;mov ax, 0x7c00 18 | ;mov si, ax 19 | ;mov ax, 1 20 | ;mov [es:si], ax 21 | jmp $ 22 | -------------------------------------------------------------------------------- /lab5/hello.cpp: -------------------------------------------------------------------------------- 1 | #include "include/io.h" 2 | 3 | int main(){ 4 | PrintStr("Hello, Mirai OS!"); 5 | PrintStr(NEWLINE); 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /lab5/help.cpp: -------------------------------------------------------------------------------- 1 | #include "include/io.h" 2 | 3 | const char *HELP_INFO = "\ 4 | Input a 1~5 for parallel running. A stream nums for serial running \n\r\ 5 | Commands:\n\r\ 6 | r Go to look user processes\n\r\ 7 | ls list all programs\n\r\ 8 | cls Clear Screen\n\r\ 9 | top View all running processes\n\r\ 10 | wake Wake a process, ex: wake 1\n\r\ 11 | suspend Suspend a process, ex: suspend 2\n\r\ 12 | kill Kill a process, ex: kill 3\n\r\ 13 | killall Kill all Processes\n\r\ 14 | uname Show os info\n\r\ 15 | Keys:\n\r\ 16 | Esc Back to Shell but not kill processes\n\r\ 17 | Ctrl+C Clear Screen\n\r\ 18 | Ctrl+Z Back to Shell and kill all processes\n\r\ 19 | "; 20 | 21 | int main(){ 22 | PrintStr(HELP_INFO,WHITE); 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /lab5/include/defines.h: -------------------------------------------------------------------------------- 1 | #ifndef _DEFINES_H_ 2 | #define _DEFINES_H_ 3 | 4 | #include 5 | 6 | #define SCREEN_WIDTH 80 7 | #define SCREEN_HEIGHT 25 8 | 9 | uint16_t PCB_SEGMENT; 10 | uint16_t PROG_SEGMENT; 11 | uint16_t MSG_SEGMENT; 12 | uint16_t MaxRunNum; 13 | 14 | void INIT_SEGMENT(){ 15 | asm volatile("int 0x21;" 16 | :"=a"(PCB_SEGMENT) 17 | :"a"(0x0300) 18 | ); 19 | 20 | asm volatile("int 0x21;" 21 | :"=a"(PROG_SEGMENT) 22 | :"a"(0x0400) 23 | ); 24 | 25 | asm volatile("int 0x21;" 26 | :"=a"(MSG_SEGMENT) 27 | :"a"(0x0500) 28 | ); 29 | asm volatile("int 0x21;" 30 | :"=a"(MaxRunNum) 31 | :"a"(0x0600) 32 | ); 33 | } 34 | 35 | const char *NEWLINE = "\r\n"; 36 | 37 | #define STREAM_MAX_LEN 16 38 | struct stream{ 39 | char str[STREAM_MAX_LEN]; 40 | uint16_t len; 41 | void put(char ch){ 42 | if (len+1 < STREAM_MAX_LEN){ 43 | str[len++] = ch; 44 | str[len] = 0; 45 | } 46 | } 47 | void pop(){ 48 | if (len > 0){ 49 | str[--len] = 0; 50 | } 51 | } 52 | stream(){ 53 | len = 0; 54 | } 55 | }; 56 | 57 | //Font Color 58 | enum Color{ 59 | BLACK = 0x00, 60 | BLUE, 61 | GREEN, 62 | CYAN, // 青色 63 | RED, 64 | CARM, // 洋红 65 | BROWN, 66 | WHITE, 67 | GRAY, 68 | LBLUE, 69 | LGREEN, 70 | LCYAN, 71 | LRED, 72 | LCARM, 73 | YELLOW, 74 | LWHITE 75 | }; 76 | 77 | void memcpy(void *dest,void *src,int size){ 78 | for (int i = 0;i < size;++i){ 79 | *(((char*)dest)+i) = *(((char*)src)+i); 80 | } 81 | } 82 | 83 | uint16_t clock(){ 84 | uint16_t chcl, dhdl; 85 | uint16_t hour,minute,second; 86 | asm volatile( 87 | "int 0x1a;" 88 | :"=c"(chcl),"=d"(dhdl) 89 | :"a"(0x0200) 90 | ); 91 | hour = (chcl >> 8) & 0xFF; 92 | minute = (chcl) & 0xFF; 93 | second = (dhdl >> 8) & 0xFF; 94 | uint16_t res = hour * 3600 + minute * 60 + second; 95 | return res; 96 | } 97 | 98 | __attribute__((regparm(1))) 99 | void sleep(uint16_t seconds){ 100 | uint16_t old = clock(); 101 | uint16_t j = clock() - old; 102 | //10 seconds 是为了避免Bug 103 | while(j <= seconds || j >= 10)j = clock() - old; 104 | } 105 | 106 | typedef char db; 107 | typedef uint16_t dw; 108 | typedef uint32_t dd; 109 | typedef uint64_t dq; 110 | 111 | extern "C" uint16_t GetKey(); 112 | extern "C" void memcpy(void *dest,const void *src,uint16_t n); 113 | 114 | #define max(a,b) ((a)>(b)?(a):(b)) 115 | #define min(a,b) ((a)<(b)?(a):(b)) 116 | 117 | #endif 118 | -------------------------------------------------------------------------------- /lab5/include/interrupt.h: -------------------------------------------------------------------------------- 1 | #ifndef _INTERRUPT_H_ 2 | #define _INTERRUPT_H_ 3 | #include "defines.h" 4 | #include "io.h" 5 | //#include 6 | 7 | //一般C++函数, 会首先将ebp入栈, 最终恢复 8 | //G++编译出来的压栈都是4字节的(32 bits), 但是我们的nasm是16位的:-( 9 | //16位G++的内嵌汇编的iret操作的是EFLAGS,ECS,EIP; 因此, 我们要将可爱的flags,cs,ip转为32位~ 10 | //不带局部变量的函数 11 | #define CPP_INT_END asm volatile("sub ebp, 8;mov [ebp],ax;mov ax,[ebp+8];mov [ebp+2],ax;mov ax,[ebp+10];mov [ebp+4],ax;mov ax,[ebp+12];mov [ebp+6],ax;mov ax,[ebp+14];mov [ebp+10],ax;mov ax,[ebp+16];mov [ebp+14],ax;xor ax,ax;mov [ebp+8],ax;mov [ebp+12],ax;mov [ebp+16],ax;mov ax,[ebp];sub sp,6;pop ebp;iret;") 12 | //带局部变量的函数(ebp保存原来的esp) 13 | //leave恢复esp(用ebp做备份), 计数 +8 -6 14 | #define CPP_INT_LEAVE asm volatile("sub ebp, 8;mov [ebp],ax;mov ax,[ebp+8];mov [ebp+2],ax;mov ax,[ebp+10];mov [ebp+4],ax;mov ax,[ebp+12];mov [ebp+6],ax;mov ax,[ebp+14];mov [ebp+10],ax;mov ax,[ebp+16];mov [ebp+14],ax;xor ax,ax;mov [ebp+8],ax;mov [ebp+12],ax;mov [ebp+16],ax;mov ax,[ebp];sub sp,6;leave;add esp, 2;iret;") 15 | __attribute__((regparm(3))) 16 | void WriteIVT(uint16_t id,uint16_t offset,uint16_t cs){ 17 | asm volatile( 18 | "push si;push es;" 19 | "mov es, ax;" 20 | "mov si, bx;" 21 | "mov es:[si], cx;" 22 | "mov es:[si+2], dx;" 23 | "pop es;pop si;" 24 | : 25 | :"a"(0),"b"(id * 4),"c"(offset),"d"(cs) 26 | ); 27 | } 28 | 29 | __attribute__((regparm(2))) 30 | void WriteIVT(uint16_t id, void (*func)()){ 31 | uint16_t cs; 32 | asm volatile("mov ax, cs;":"=a"(cs)); 33 | WriteIVT(id,(long)func,cs); 34 | } 35 | 36 | __attribute__((regparm(1))) 37 | void ExecuteINT(uint16_t id){ 38 | uint16_t ip, cs; 39 | asm volatile( 40 | "push es;" 41 | "mov es, ax;" 42 | "mov ax, es:[bx];" 43 | "mov bx, es:[bx + 2];" 44 | "pop es;" 45 | :"=a"(ip),"=b"(cs) 46 | :"a"(0),"b"(id * 4) 47 | ); 48 | uint16_t ocs; 49 | asm volatile("mov ax, cs;":"=a"(ocs)); 50 | //不知道为什么, 一定要加下面这一句, 否则崩溃:-( 51 | PrintStr("Execute interrupt 0x"); 52 | PrintHex(id);PrintStr(NEWLINE); 53 | char addr[4]; 54 | *((uint16_t*)(addr)) = ip; 55 | *((uint16_t*)(addr+2)) = cs; 56 | asm volatile( 57 | "push es;" 58 | "mov es, ax;" 59 | "pushf;" 60 | "call far ptr es:[bx];" 61 | "pop es;" 62 | : 63 | :"a"(ocs),"b"(addr) 64 | ); 65 | } 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /lab5/include/port.h: -------------------------------------------------------------------------------- 1 | #ifndef _PORT_H_ 2 | #define _PORT_H_ 3 | /* 4 | ;22H进程, 进程通信 5 | 6 | ;ah = 00h 读 7 | ;ah = 01h 写 8 | ;ah = 02h 信号量设置(bh=0, 清零; bh=1, 加1; bh=2, 减1; bh=3, 设置为bl值) 9 | ;ah = 03h 设置端口 10 | ;ah = 04h 关闭端口 11 | ;ah = 05h 只返回信号量 12 | ;al = 端口值 13 | ;基地址bx, 缓存大小cx, 段地址dx 14 | ;返回信号量(ax) 15 | */ 16 | #include "defines.h" 17 | 18 | __attribute__((regparm(3))) 19 | void SetPort(uint8_t portID, void* varAddr, uint16_t size){ 20 | uint16_t cs; 21 | asm volatile("mov ax,cs;":"=a"(cs)); 22 | asm volatile("int 0x22;" 23 | : 24 | :"a"((3 << 8) | portID), "b"(varAddr), "c"(size), "d"(cs) 25 | ); 26 | } 27 | 28 | __attribute__((regparm(3))) 29 | uint8_t ReadPort(uint8_t portID, void* varAddr, uint16_t size){ 30 | uint16_t cs; 31 | uint8_t v; 32 | asm volatile("mov ax,cs;":"=a"(cs)); 33 | asm volatile("int 0x22;" 34 | :"=a"(v) 35 | :"a"((0 << 8) | portID), "b"(varAddr), "c"(size), "d"(cs) 36 | ); 37 | return v; 38 | } 39 | 40 | __attribute__((regparm(3))) 41 | void WritePort(uint8_t portID, void* varAddr, uint16_t size){ 42 | uint16_t cs; 43 | asm volatile("mov ax,cs;":"=a"(cs)); 44 | asm volatile("int 0x22;" 45 | : 46 | :"a"((1 << 8) | portID), "b"(varAddr), "c"(size), "d"(cs) 47 | ); 48 | } 49 | 50 | 51 | __attribute__((regparm(2))) 52 | void SetPortMsgV(uint8_t portID, uint8_t v){ 53 | uint16_t cs; 54 | asm volatile("mov ax,cs;":"=a"(cs)); 55 | asm volatile("int 0x22;" 56 | : 57 | :"a"((2<<8) | portID), "b"((3<<8) | v) 58 | ); 59 | } 60 | 61 | 62 | __attribute__((regparm(1))) 63 | uint8_t GetPortMsgV(uint8_t portID){ 64 | uint8_t v; 65 | asm volatile("int 0x22;" 66 | :"=a"(v) 67 | :"a"((5<<8) | portID) 68 | ); 69 | return v; 70 | } 71 | #endif 72 | -------------------------------------------------------------------------------- /lab5/include/string.h: -------------------------------------------------------------------------------- 1 | #ifndef _STRING_H_ 2 | #define _STRING_H_ 3 | 4 | #include "defines.h" 5 | 6 | __attribute__((regparm(1))) 7 | int strlen(const char *s){ 8 | int i = 0; 9 | while(*(s++))i++; 10 | return i; 11 | } 12 | 13 | __attribute__((regparm(2))) 14 | int strcmp(const char *astr,const char *bstr){ 15 | // = 0 16 | // < -1 17 | // > 1 18 | while ((*astr) && (*bstr)){ 19 | if (*astr != *bstr){ 20 | if (*astr < *bstr)return -1; 21 | return 1; 22 | } 23 | ++astr; 24 | ++bstr; 25 | } 26 | return (*astr) - (*bstr); 27 | } 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /lab5/include/version.h: -------------------------------------------------------------------------------- 1 | #define RELEASE_TIMES 372 2 | -------------------------------------------------------------------------------- /lab5/inttest.asm: -------------------------------------------------------------------------------- 1 | org 100h 2 | 3 | int 33h 4 | int 34h 5 | int 35h 6 | int 36h 7 | ;int 21h 8 | 9 | int 20h 10 | jmp $ 11 | -------------------------------------------------------------------------------- /lab5/kan.asm: -------------------------------------------------------------------------------- 1 | ;My Name 2 | ;Jackie Wu (Wu Kan) 3 | ;14348134 4 | 5 | org 100H 6 | ;org 7c00h 7 | outDelay equ 40000 8 | inDelay equ 500 9 | 10 | ;set data segment 11 | mov ax,cs 12 | mov ds,ax 13 | 14 | ;text window 15 | ;25 * 80 16 | mov ax,0B800h 17 | mov es,ax 18 | 19 | %macro SETMEM 2 20 | mov ax,%2 21 | mov [%1],ax 22 | %endmacro 23 | 24 | START: 25 | call DELAY 26 | call SHOWINFO 27 | call DELAY 28 | 29 | SETMEM pos,1405H 30 | SETMEM vel,0FF01H 31 | mov cx,8 32 | call LINE 33 | 34 | SETMEM pos,1109H 35 | SETMEM vel,0001H 36 | mov cx,14 37 | call LINE 38 | 39 | SETMEM pos,1705H 40 | SETMEM vel,0001H 41 | mov cx,7 42 | call LINE 43 | 44 | SETMEM pos,1705H 45 | SETMEM vel,0100H 46 | mov cx,10 47 | call LINE 48 | 49 | SETMEM vel,0001H 50 | mov cx,7 51 | call LINE 52 | 53 | SETMEM pos,170BH 54 | SETMEM vel,0100H 55 | mov cx,10 56 | call LINE 57 | 58 | SETMEM pos,170DH 59 | SETMEM vel,0001H 60 | mov cx,8 61 | call LINE 62 | 63 | SETMEM pos,1615H 64 | SETMEM vel,0FF01H 65 | mov cx,2 66 | call LINE 67 | 68 | SETMEM pos,1B0DH 69 | SETMEM vel,0001H 70 | mov cx,10 71 | call LINE 72 | 73 | SETMEM pos,1F0DH 74 | SETMEM vel,0001H 75 | mov cx,9 76 | call LINE 77 | 78 | SETMEM vel,0100H 79 | mov cx,4 80 | call LINE 81 | 82 | SETMEM vel,00FFH 83 | mov cx,2 84 | call LINE 85 | 86 | call DELAY 87 | call DELAY 88 | call DELAY 89 | call DELAY 90 | call DELAY 91 | mov ax,3 92 | int 10h 93 | jmp START 94 | 95 | LINE: 96 | ;cx is the len of line 97 | LINELOOP: 98 | call DELAY 99 | call SHOW 100 | call MOVEPOS 101 | loop LINELOOP 102 | ret 103 | 104 | SHOWINFO: 105 | mov cx,[msgLen] 106 | 107 | mov si,message 108 | 109 | mov di, (1*80 + 1) * 2 110 | 111 | printChar: 112 | mov al,[si] 113 | inc si 114 | mov ah,07h 115 | mov [es:di],ax 116 | add di,2 117 | loop printChar 118 | ret 119 | 120 | DELAY: 121 | push cx 122 | mov cx, outDelay 123 | LOOP1: 124 | mov ax, inDelay 125 | LOOP2: 126 | dec ax 127 | jg LOOP2 128 | loop LOOP1 129 | pop cx 130 | 131 | ret 132 | 133 | MOVEPOS: 134 | mov ax,[pos] 135 | mov bx,[vel] 136 | add ah,bh 137 | add al,bl 138 | mov [pos],ax 139 | ret 140 | 141 | SHOW: 142 | push cx 143 | mov bx,[pos] 144 | mov ax,0 145 | mov al,bl 146 | mov dx,80 147 | mul dx 148 | mov dx,0 149 | mov dl,bh 150 | add ax,dx 151 | mov cx,2 152 | mul cx 153 | mov bx, ax 154 | 155 | mov al,[char] 156 | inc al 157 | cmp al,'Z' 158 | jna LESSZ 159 | mov al,'A' 160 | LESSZ: 161 | mov [char],al 162 | mov ah,[color] 163 | and ah,0Fh 164 | inc byte[color] 165 | mov [es:bx],ax 166 | pop cx 167 | ret 168 | 169 | DATA: 170 | message db "My Name is" 171 | msgLen dw $-message 172 | 173 | pos dw 0000h 174 | vel dw 0000h 175 | char db 'a' 176 | color db 09H 177 | 178 | times 510-($-$$) db 0 179 | dw 0xaa55 180 | -------------------------------------------------------------------------------- /lab5/linker_100.ld: -------------------------------------------------------------------------------- 1 | ENTRY(main); 2 | SECTIONS 3 | { 4 | . = 0x100; 5 | .text : AT(0x100) 6 | { 7 | _text = .; 8 | *(.text); 9 | _text_end = .; 10 | } 11 | .data : 12 | { 13 | _data = .; 14 | *(.bss); 15 | *(.bss*); 16 | *(.data); 17 | *(.rodata*); 18 | *(COMMON) 19 | _data_end = .; 20 | } 21 | /DISCARD/ : 22 | { 23 | *(.note*); 24 | *(.iplt*); 25 | *(.igot*); 26 | *(.rel*); 27 | *(.comment); 28 | /* add any unwanted sections spewed out by your version of gcc and flags here */ 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /lab5/ls.cpp: -------------------------------------------------------------------------------- 1 | #include "include/io.h" 2 | #include "include/disk.h" 3 | 4 | char buf[512]; 5 | Entry e; 6 | 7 | const char Months[12][4] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}; 8 | 9 | __attribute__((regparm(1))) 10 | void PrintDate(uint16_t date){ 11 | //Month 12 | uint8_t month = (date >> 5) & 0xF; 13 | PrintStr(Months[month - 1]); 14 | PrintChar('.'); 15 | uint8_t day = (date) & 0x1F; 16 | PrintNum(day); 17 | PrintChar(','); 18 | uint16_t year = uint16_t((date >> 9) & 0x7F) + 1980; 19 | PrintNum(year); 20 | } 21 | 22 | __attribute__((regparm(1))) 23 | void Print2Num(int num){ 24 | PrintChar(num / 10 + '0'); 25 | PrintChar(num % 10 + '0'); 26 | } 27 | 28 | __attribute__((regparm(2))) 29 | void PrintTime(uint16_t t,uint8_t offset){ 30 | uint8_t second = (t & 0x1F) * 2; 31 | uint8_t minute = ((t>>5) & 0x3F); 32 | uint8_t hour = (((t>>11) & 0x1F) + offset)%24; 33 | Print2Num(hour); 34 | PrintChar(':'); 35 | Print2Num(minute); 36 | PrintChar(':'); 37 | Print2Num(second); 38 | } 39 | 40 | char dbuf[1024]; 41 | __attribute__((regparm(1))) 42 | uint16_t GetNextCluster(uint16_t u){ 43 | //get fat 44 | int t = u * 3 / 2; 45 | int p = t / 512; 46 | int o = t % 512; 47 | ReadFloppy(1 + p,2,dbuf); 48 | //uint16_t w = ((buf[o+1]&0xFF) << 8) | (buf[o]&0xFF); 49 | //注意位扩展:-( 50 | uint16_t w = *(uint16_t*)(dbuf + o); 51 | if (u % 2 == 0){ 52 | w &= 0xFFF; 53 | }else{ 54 | w = (w >> 4) & 0xFFF; 55 | } 56 | return w; 57 | } 58 | 59 | __attribute__((regparm(1))) 60 | void PrintClusters(uint16_t u){ 61 | PrintNum(u); 62 | u = GetNextCluster(u); 63 | for(int i = 0;i < 5 &&(!(u >= 0xFF8));++i){ 64 | PrintChar(','); 65 | PrintNum(u); 66 | u = GetNextCluster(u); 67 | } 68 | if (!(u >= 0xFF8)){ 69 | PrintStr(",..."); 70 | } 71 | } 72 | int main(){ 73 | 74 | bool first = true; 75 | for (int i = 19;i < 19 + 14;++i){ 76 | ReadFloppy(i,1,buf); 77 | for (int j = 0;j < 512/32;++j){ 78 | for (int k = 0;k < 32;++k){ 79 | *(((char*)&e) + k) = buf[k + j*32]; 80 | } 81 | if (e.DIR_Name[10] == 0)continue; 82 | if (first){ 83 | first = false; 84 | PrintStr("Filename Size Date Time(UTC+8) Clusters",LBLUE); 85 | PrintStr(NEWLINE); 86 | } 87 | //Print Name 88 | int count = 0; 89 | for (int i = 0;i < 8;++i){ 90 | if(e.DIR_Name[i] && e.DIR_Name[i] != ' '){ 91 | PrintChar(e.DIR_Name[i]); 92 | ++count; 93 | } 94 | else break; 95 | } 96 | PrintChar('.'); 97 | for (int i = 8;i < 11;++i){ 98 | if(e.DIR_Name[i] && e.DIR_Name[i] != ' '){ 99 | PrintChar(e.DIR_Name[i]); 100 | ++count; 101 | } 102 | else break; 103 | } 104 | for (int i = count;i < 12;++i)PrintChar(' '); 105 | count = PrintNum(e.DIR_FileSize); 106 | for(int i = count;i < 6;++i)PrintChar(' '); 107 | PrintDate(e.LAST_WrtDate); 108 | PrintChar(' '); 109 | //使用东八区时间 110 | PrintTime(e.LAST_WrtTime, 8); 111 | //Print Clusters 112 | PrintStr(" "); 113 | PrintClusters(e.DIR_FstClus); 114 | PrintStr(NEWLINE); 115 | } 116 | } 117 | 118 | return 0; 119 | } 120 | -------------------------------------------------------------------------------- /lab5/ouch.cpp: -------------------------------------------------------------------------------- 1 | #include "include/io.h" 2 | 3 | int main(){ 4 | DrawText("Ouch! Ouch!",24,1,YELLOW); 5 | sleep(1); 6 | DrawText(" ",24,1,YELLOW); 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /lab5/pic/51.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab5/pic/51.png -------------------------------------------------------------------------------- /lab5/pic/54.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab5/pic/54.png -------------------------------------------------------------------------------- /lab5/report/14348134吴侃lab5_ver2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab5/report/14348134吴侃lab5_ver2.pdf -------------------------------------------------------------------------------- /lab5/tools/key.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | struct K{ 8 | string name; 9 | string smm[4]; 10 | string asc[4]; 11 | }; 12 | 13 | int main(){ 14 | ifstream fin("key.txt"); 15 | string name; 16 | string temp; 17 | 18 | vector ks; 19 | do{ 20 | K k; 21 | fin >> name; 22 | if(fin.eof())break; 23 | for (int i = 0;i < name.size();++i){ 24 | char c = name[i]; 25 | if (c >= 'a' && c <= 'z')c = c - 'a' +'A'; 26 | k.name += c; 27 | } 28 | for (int i = 0;i < 4;++i){ 29 | fin >> k.smm[i]; 30 | fin >> k.asc[i]; 31 | } 32 | ks.push_back(k); 33 | }while(!fin.eof()); 34 | ofstream fout("keyboard.h"); 35 | fout << "#ifndef _KEY_BOARD_H_" << endl; 36 | fout << "#define _KEY_BOARD_H_" << endl << endl; 37 | int o = 0; 38 | for (size_t i = 0;i < ks.size();++i){ 39 | K &k = ks[i]; 40 | string name = "KEY_" + k.name; 41 | fout << "#define " << name << " " << "0x" << k.smm[o] << k.asc[o] << endl; 42 | } 43 | o = 1; 44 | for (size_t i = 0;i < ks.size();++i){ 45 | K &k = ks[i]; 46 | string name = "KEY_SHIFT_" + k.name; 47 | fout << "#define " << name << " " << "0x" << k.smm[o] << k.asc[o] << endl; 48 | } 49 | o = 2; 50 | for (size_t i = 0;i < ks.size();++i){ 51 | K &k = ks[i]; 52 | string name = "KEY_CTRL_" + k.name; 53 | fout << "#define " << name << " " << "0x" << k.smm[o] << k.asc[o] << endl; 54 | } 55 | o = 3; 56 | for (size_t i = 0;i < ks.size();++i){ 57 | K &k = ks[i]; 58 | string name = "KEY_ALT_" + k.name; 59 | fout << "#define " << name << " " << "0x" << k.smm[o] << k.asc[o] << endl; 60 | } 61 | fout << endl << endl << "#endif" << endl; 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /lab5/tools/keybuild: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab5/tools/keybuild -------------------------------------------------------------------------------- /lab5/wkcn1.asm: -------------------------------------------------------------------------------- 1 | ;Running Ball 2 | ;Jackie Wu (Wu Kan) 3 | ;14348134 4 | ;wkcn@live.cn 5 | 6 | ;totalDelay = outDelay * inDelay 7 | org 100H 8 | outDelay equ 40000 9 | inDelay equ 1000 10 | 11 | ;80 x 25 12 | SCREEN_X equ 80 13 | SCREEN_Y equ 25 14 | ;Ball in this Rect 15 | MIN_X equ 40 16 | MIN_Y equ 0 17 | MAX_X equ 80 18 | MAX_Y equ 13 19 | 20 | ;set data segment 21 | ;mov ax,07c0h 22 | mov ax,cs 23 | mov ds,ax 24 | 25 | ;text window 26 | ;25 * 80 27 | mov ax,0B800h 28 | mov es,ax 29 | 30 | 31 | %macro SINGLE 4 32 | ;pos dw 0000h ;from 0,0 33 | ;vel dw 0101h ;v = (1,1) 34 | ;char db '*' 35 | ;color db 07H 36 | 37 | mov ax, [%1] 38 | mov [pos], ax 39 | mov ax, [%2] 40 | mov [vel], ax 41 | mov al, [%3] 42 | mov [char], al 43 | mov al, [%4] 44 | mov [color], al 45 | 46 | call PLAY 47 | 48 | mov ax, [pos] 49 | mov [%1], ax 50 | mov ax, [vel] 51 | mov [%2], ax 52 | %endmacro 53 | 54 | START: 55 | call DELAY 56 | ;call PLAY 57 | SINGLE pos1,vel1,char1,color1 58 | SINGLE pos2,vel2,char2,color2 59 | ;SINGLE pos3,vel3,char3,color3 60 | call SHOWNAME 61 | jmp START 62 | 63 | PLAY: 64 | call SETPOINTER 65 | call ELIMINATE 66 | 67 | call UPDATEPOS 68 | 69 | call SETPOINTER 70 | call SHOW 71 | ret 72 | 73 | SHOWNAME: 74 | mov cx,[msgLen] 75 | 76 | mov si,message 77 | 78 | mov di, (1*80 + 1) * 2 79 | 80 | mov dl,[msgColor] 81 | 82 | printChar: 83 | mov al,[si] 84 | inc si 85 | and dl,0Fh 86 | mov ah,dl 87 | add dl,1 88 | mov [es:di],ax 89 | add di,2 90 | loop printChar 91 | 92 | inc byte[msgColor] 93 | 94 | ret 95 | 96 | DELAY: 97 | mov cx, outDelay 98 | LOOP1: 99 | mov ax, inDelay 100 | LOOP2: 101 | dec ax 102 | jg LOOP2 103 | loop LOOP1 104 | 105 | ret 106 | 107 | UPDATEPOS: 108 | ;parameter: pos, vel 109 | mov ax,[pos] 110 | mov bx,[vel] 111 | 112 | ;update x 113 | add ah,bh 114 | cmp ah,MIN_X 115 | ja XNZ 116 | ;if x <= MIN_X 117 | mov bh,1 118 | XNZ: 119 | CMP ah,MAX_X-1 120 | jb XNF 121 | ;if x >= MAX_X-1 122 | mov bh,-1 123 | XNF: 124 | ;update y 125 | add al,bl 126 | cmp al,MIN_Y 127 | ja YNZ 128 | ;if y <= MIN_Y 129 | mov bl,1 130 | YNZ: 131 | CMP al,MAX_Y-1 132 | jb YNF 133 | ;if y >= MAX_Y-1 134 | mov bl,-1 135 | YNF: 136 | mov [pos],ax 137 | mov [vel],bx 138 | ret 139 | 140 | SETPOINTER: 141 | ;parameter pos, char 142 | mov ax, 0 143 | mov bx, [pos] ; bx = (x,y) 144 | mov al, bl 145 | mov cx, SCREEN_X 146 | mul cx ; ax *= SCREEN_X namely ax = y * SCREEN_X 147 | mov cx, 0 148 | mov cl, bh 149 | add ax, cx ; ax += x 150 | mov cx, 2 151 | mul cx 152 | mov bx, ax 153 | ret 154 | 155 | SHOW: 156 | ;new 157 | mov al, [char] 158 | mov ah, [color] 159 | mov [es:bx],ax 160 | ret 161 | 162 | ELIMINATE: 163 | ;clean 164 | mov ax, 0 165 | mov [es:bx],ax 166 | ret 167 | 168 | 169 | 170 | 171 | DATA: 172 | message db "WuKan's Program 1" 173 | msgLen dw $-message 174 | msgColor db 00h 175 | 176 | outCount dw outDelay 177 | inCount dw inDelay 178 | 179 | pos dw 0000h ;from 0,0 180 | vel dw 0101h ;v = (1,1) 181 | char db '*' 182 | color db 03H 183 | 184 | ;elements 185 | pos1 dw 0000h 186 | vel1 dw 0101h 187 | char1 db '*' 188 | color1 db 03H ;green 189 | 190 | pos2 dw 1003h 191 | vel2 dw 01FFh 192 | char2 db 'A' 193 | color2 db 0CFH ;twinkle red and light white 194 | 195 | pos3 dw 2019h 196 | vel3 dw 0FFFFh 197 | char3 db '@' 198 | color3 db 0EH ;yello 199 | 200 | times 510-($-$$) db 0 201 | dw 0xaa55 202 | -------------------------------------------------------------------------------- /lab5/wkcn3.asm: -------------------------------------------------------------------------------- 1 | ;Running Ball 2 | ;Jackie Wu (Wu Kan) 3 | ;14348134 4 | ;wkcn@live.cn 5 | 6 | ;totalDelay = outDelay * inDelay 7 | org 100H 8 | outDelay equ 47000 9 | inDelay equ 1000 10 | 11 | ;80 x 25 12 | SCREEN_X equ 80 13 | SCREEN_Y equ 25 14 | ;Ball in this Rect 15 | MIN_X equ 0 16 | MIN_Y equ 13 17 | MAX_X equ 40 18 | MAX_Y equ 25 19 | 20 | ;set data segment 21 | ;mov ax,07c0h 22 | mov ax,cs 23 | mov ds,ax 24 | 25 | ;text window 26 | ;25 * 80 27 | mov ax,0B800h 28 | mov es,ax 29 | 30 | 31 | %macro SINGLE 4 32 | ;pos dw 0000h ;from 0,0 33 | ;vel dw 0101h ;v = (1,1) 34 | ;char db '*' 35 | ;color db 07H 36 | 37 | mov ax, [%1] 38 | mov [pos], ax 39 | mov ax, [%2] 40 | mov [vel], ax 41 | mov al, [%3] 42 | mov [char], al 43 | mov al, [%4] 44 | mov [color], al 45 | 46 | call PLAY 47 | 48 | mov ax, [pos] 49 | mov [%1], ax 50 | mov ax, [vel] 51 | mov [%2], ax 52 | %endmacro 53 | 54 | START: 55 | call DELAY 56 | ;call PLAY 57 | SINGLE pos1,vel1,char1,color1 58 | SINGLE pos2,vel2,char2,color2 59 | SINGLE pos3,vel3,char3,color3 60 | call SHOWNAME 61 | jmp START 62 | 63 | PLAY: 64 | call SETPOINTER 65 | call ELIMINATE 66 | 67 | call UPDATEPOS 68 | 69 | call SETPOINTER 70 | call SHOW 71 | ret 72 | 73 | SHOWNAME: 74 | mov cx,[msgLen] 75 | 76 | mov si,message 77 | 78 | mov di, (1*80 + 1) * 2 79 | 80 | mov dl,[msgColor] 81 | 82 | printChar: 83 | mov al,[si] 84 | inc si 85 | and dl,0Fh 86 | mov ah,dl 87 | add dl,1 88 | mov [es:di],ax 89 | add di,2 90 | loop printChar 91 | 92 | inc byte[msgColor] 93 | 94 | ret 95 | 96 | DELAY: 97 | mov cx, outDelay 98 | LOOP1: 99 | mov ax, inDelay 100 | LOOP2: 101 | dec ax 102 | jg LOOP2 103 | loop LOOP1 104 | 105 | ret 106 | 107 | UPDATEPOS: 108 | ;parameter: pos, vel 109 | mov ax,[pos] 110 | mov bx,[vel] 111 | 112 | ;update x 113 | add ah,bh 114 | cmp ah,MIN_X 115 | ja XNZ 116 | ;if x <= MIN_X 117 | mov bh,1 118 | XNZ: 119 | CMP ah,MAX_X-1 120 | jb XNF 121 | ;if x >= MAX_X-1 122 | mov bh,-1 123 | XNF: 124 | ;update y 125 | add al,bl 126 | cmp al,MIN_Y 127 | ja YNZ 128 | ;if y <= MIN_Y 129 | mov bl,1 130 | YNZ: 131 | CMP al,MAX_Y-1 132 | jb YNF 133 | ;if y >= MAX_Y-1 134 | mov bl,-1 135 | YNF: 136 | mov [pos],ax 137 | mov [vel],bx 138 | ret 139 | 140 | SETPOINTER: 141 | ;parameter pos, char 142 | mov ax, 0 143 | mov bx, [pos] ; bx = (x,y) 144 | mov al, bl 145 | mov cx, SCREEN_X 146 | mul cx ; ax *= SCREEN_X namely ax = y * SCREEN_X 147 | mov cx, 0 148 | mov cl, bh 149 | add ax, cx ; ax += x 150 | mov cx, 2 151 | mul cx 152 | mov bx, ax 153 | ret 154 | 155 | SHOW: 156 | ;new 157 | mov al, [char] 158 | mov ah, [color] 159 | mov [es:bx],ax 160 | ret 161 | 162 | ELIMINATE: 163 | ;clean 164 | mov ax, 0 165 | mov [es:bx],ax 166 | ret 167 | 168 | 169 | 170 | 171 | DATA: 172 | message db "WuKan's Program 3" 173 | msgLen dw $-message 174 | msgColor db 00h 175 | 176 | outCount dw outDelay 177 | inCount dw inDelay 178 | 179 | pos dw 0000h ;from 0,0 180 | vel dw 0101h ;v = (1,1) 181 | char db '*' 182 | color db 03H 183 | 184 | ;elements 185 | pos1 dw 0000h 186 | vel1 dw 0101h 187 | char1 db '*' 188 | color1 db 03H ;green 189 | 190 | pos2 dw 1003h 191 | vel2 dw 01FFh 192 | char2 db 'A' 193 | color2 db 0CFH ;twinkle red and light white 194 | 195 | pos3 dw 2019h 196 | vel3 dw 0FFFFh 197 | char3 db '@' 198 | color3 db 0EH ;yello 199 | 200 | times 510-($-$$) db 0 201 | dw 0xaa55 202 | -------------------------------------------------------------------------------- /lab6/Makefile: -------------------------------------------------------------------------------- 1 | BUILD_DIR = build 2 | DISK_DIR = disk 3 | KITS_DIR = kits 4 | SOURCE_DIR = source 5 | IMAGE_NAME= MiraiOS.img 6 | CC = g++ 7 | CFLAGS = -Iinclude -c -m16 -march=i386 -masm=intel -nostdlib -ffreestanding -mpreferred-stack-boundary=2 -lgcc -shared -std=c++11 -Wno-int-to-void-pointer-cast -fpermissive 8 | 9 | AS = nasm 10 | ASFLAGS = 11 | LD = ld 12 | LDFLAGS = -m elf_i386 -N 13 | 14 | #如果不加-fda, 虽然能读Loader, 但无法读扇区:-( 15 | QEMU = qemu-system-i386 16 | QEMUFLAGS = -fda 17 | 18 | BOCHS = bochs 19 | BOCHSFLAGS = -q -f bochsrc.bxrc 20 | 21 | all: build_dir counter write_image write_knl build_progs 22 | 23 | 24 | build_dir: 25 | -mkdir $(BUILD_DIR) 26 | -mkdir $(DISK_DIR) 27 | ./counter 28 | 29 | write_image: loadknl.bin 30 | dd if=/dev/zero of=$(IMAGE_NAME) count=2880 31 | dd if=$(BUILD_DIR)/loadknl.bin of=$(IMAGE_NAME) conv=notrunc 32 | 33 | write_knl: kernel.bin 34 | mount -o loop $(IMAGE_NAME) disk/ 35 | cp $(BUILD_DIR)/kernel.bin $(DISK_DIR)/ 36 | umount $(DISK_DIR)/ 37 | 38 | build_progs: wkcn1.com wkcn2.com wkcn3.com wkcn4.com kan.com\ 39 | bs.com bpb.com ls.com help.com\ 40 | box.com\ 41 | testint.com testport.com testnew.com\ 42 | fork1.com fork2.com alpha.com\ 43 | mat.com letter.com fruit.com 44 | 45 | mount -o loop $(IMAGE_NAME) disk/ 46 | 47 | for name in $^; do\ 48 | cp $(BUILD_DIR)/$$name $(DISK_DIR)/;\ 49 | done 50 | 51 | umount $(DISK_DIR)/ 52 | 53 | loadknl.bin: $(SOURCE_DIR)/loadknl.asm 54 | $(AS) $(ASFLAGS) -f bin $^ -o $(BUILD_DIR)/$@ 55 | 56 | kernel.bin: kernel.o os.o 57 | $(LD) $(LDFLAGS) -Ttext 0x7e00 --oformat binary $(BUILD_DIR)/kernel.o $(BUILD_DIR)/os.o -o $(BUILD_DIR)/$@ 58 | 59 | 60 | %.s: %.cpp 61 | $(CC) $(CFLAGS) -S $< -o $(BUILD_DIR)/$@ 62 | %.o: %.c 63 | $(CC) $(CFLAGS) $< -o $(BUILD_DIR)/$@ 64 | %.o: $(SOURCE_DIR)/%.cpp 65 | $(CC) $(CFLAGS) $< -o $(BUILD_DIR)/$@ 66 | %.o: $(SOURCE_DIR)/%.asm 67 | $(AS) $(ASFLAGS) -f elf32 $^ -o $(BUILD_DIR)/$@ 68 | %.com: %.o header.o 69 | #$(LD) $(LDFLAGS) -Ttext 0x100 --oformat binary $(BUILD_DIR)/header.o $(BUILD_DIR)/$< -o $(BUILD_DIR)/$@ 70 | $(LD) $(LDFLAGS) -T $(SOURCE_DIR)/linker_100.ld --oformat binary $(BUILD_DIR)/header.o $(BUILD_DIR)/$< -o $(BUILD_DIR)/$@ 71 | %.com: $(SOURCE_DIR)/%.asm 72 | $(AS) $(ASFLAGS) -f bin $^ -o $(BUILD_DIR)/$@ 73 | 74 | qemu: 75 | $(QEMU) $(QEMUFLAGS) $(IMAGE_NAME) 76 | 77 | run: qemu 78 | 79 | bochs: 80 | $(BOCHS) $(BOCHSFLAGS) 81 | 82 | build_counter: 83 | g++ counter.cpp -o counter 84 | 85 | clean: 86 | -rm -rf $(BUILD_DIR) 87 | -rm -rf $(DISK_DIR) 88 | -------------------------------------------------------------------------------- /lab6/ReadMe.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab6/ReadMe.txt -------------------------------------------------------------------------------- /lab6/counter: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab6/counter -------------------------------------------------------------------------------- /lab6/include/defines.h: -------------------------------------------------------------------------------- 1 | #ifndef _DEFINES_H_ 2 | #define _DEFINES_H_ 3 | 4 | #include 5 | 6 | #define SCREEN_WIDTH 80 7 | #define SCREEN_HEIGHT 25 8 | 9 | uint16_t PCB_SEGMENT; 10 | uint16_t PROG_SEGMENT; 11 | uint16_t MSG_SEGMENT; 12 | uint16_t MaxRunNum; 13 | 14 | void INIT_SEGMENT(){ 15 | asm volatile("int 0x21;" 16 | :"=a"(PCB_SEGMENT) 17 | :"a"(0x0300) 18 | ); 19 | 20 | asm volatile("int 0x21;" 21 | :"=a"(PROG_SEGMENT) 22 | :"a"(0x0400) 23 | ); 24 | 25 | asm volatile("int 0x21;" 26 | :"=a"(MSG_SEGMENT) 27 | :"a"(0x0500) 28 | ); 29 | asm volatile("int 0x21;" 30 | :"=a"(MaxRunNum) 31 | :"a"(0x0600) 32 | ); 33 | } 34 | 35 | const char *NEWLINE = "\r\n"; 36 | 37 | #define STREAM_MAX_LEN 16 38 | struct stream{ 39 | char str[STREAM_MAX_LEN]; 40 | uint16_t len; 41 | void put(char ch){ 42 | if (len+1 < STREAM_MAX_LEN){ 43 | str[len++] = ch; 44 | str[len] = 0; 45 | } 46 | } 47 | void pop(){ 48 | if (len > 0){ 49 | str[--len] = 0; 50 | } 51 | } 52 | stream(){ 53 | len = 0; 54 | } 55 | }; 56 | 57 | //Font Color 58 | enum Color{ 59 | BLACK = 0x00, 60 | BLUE, 61 | GREEN, 62 | CYAN, // 青色 63 | RED, 64 | CARM, // 洋红 65 | BROWN, 66 | WHITE, 67 | GRAY, 68 | LBLUE, 69 | LGREEN, 70 | LCYAN, 71 | LRED, 72 | LCARM, 73 | YELLOW, 74 | LWHITE 75 | }; 76 | 77 | void memcpy(void *dest,void *src,int size){ 78 | for (int i = 0;i < size;++i){ 79 | *(((char*)dest)+i) = *(((char*)src)+i); 80 | } 81 | } 82 | 83 | uint16_t clock(){ 84 | uint16_t chcl, dhdl; 85 | uint16_t hour,minute,second; 86 | asm volatile( 87 | "int 0x1a;" 88 | :"=c"(chcl),"=d"(dhdl) 89 | :"a"(0x0200) 90 | ); 91 | hour = (chcl >> 8) & 0xFF; 92 | minute = (chcl) & 0xFF; 93 | second = (dhdl >> 8) & 0xFF; 94 | uint16_t res = hour * 3600 + minute * 60 + second; 95 | return res; 96 | } 97 | 98 | __attribute__((regparm(1))) 99 | void sleep(uint16_t seconds){ 100 | uint16_t old = clock(); 101 | uint16_t j = clock() - old; 102 | //10 seconds 是为了避免Bug 103 | while(j <= seconds || j >= 10)j = clock() - old; 104 | } 105 | 106 | typedef char db; 107 | typedef uint16_t dw; 108 | typedef uint32_t dd; 109 | typedef uint64_t dq; 110 | 111 | extern "C" uint16_t GetKey(); 112 | extern "C" void memcpy(void *dest,const void *src,uint16_t n); 113 | 114 | #define max(a,b) ((a)>(b)?(a):(b)) 115 | #define min(a,b) ((a)<(b)?(a):(b)) 116 | 117 | #endif 118 | -------------------------------------------------------------------------------- /lab6/include/fork.h: -------------------------------------------------------------------------------- 1 | #ifndef _TASK_H_ 2 | #define _TASK_H_ 3 | 4 | #include "pcb.h" 5 | #include "memory.h" 6 | 7 | uint8_t fork(){ 8 | INIT_SEGMENT(); 9 | ScheduleOFF; 10 | Schedule; 11 | uint16_t runid = GetRunID(); 12 | LoadPCB(runid); // note:IP! 13 | if (_p.KIND == K_FORK){ 14 | SetTaskAttr(runid,&_p.KIND,uint8_t(K_PROG)); 15 | ScheduleON; 16 | return 0; // 子进程返回0 17 | } 18 | uint8_t newID = FindEmptyPCB(); 19 | uint16_t addrseg = allocate(_p.SSIZE); 20 | if (addrseg == 0xFFFF){ 21 | ScheduleON; 22 | return 0xFF; 23 | } 24 | //[ds:si] -> [es:di] 25 | asm volatile("push ds;push si;push es;push di;" 26 | "mov ds,ax;" 27 | "mov es,dx;" 28 | "xor si,si;" 29 | "xor di,di;" 30 | "cld;" 31 | "COPY_PROG:;" 32 | "movsw;movsw;movsw;movsw;" 33 | "movsw;movsw;movsw;movsw;" 34 | "loop COPY_PROG;" 35 | "pop di;pop es;pop si;pop ds;" 36 | : 37 | :"a"(_p.SEG),"d"(addrseg),"c"(_p.SSIZE) 38 | ); 39 | 40 | // 注意, ID与RunID类型是不同的,db和dw 41 | _p.ID = newID; 42 | _p.CS = addrseg; 43 | _p.DS = addrseg; 44 | _p.SS = addrseg; 45 | _p.SEG = addrseg; 46 | _p.PARENT_ID = runid; 47 | _p.KIND = K_FORK; 48 | 49 | WritePCB(newID); 50 | INC_RunNum; 51 | ScheduleON; 52 | return newID; 53 | } 54 | 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /lab6/include/interrupt.h: -------------------------------------------------------------------------------- 1 | #ifndef _INTERRUPT_H_ 2 | #define _INTERRUPT_H_ 3 | #include "defines.h" 4 | #include "io.h" 5 | //#include 6 | 7 | //一般C++函数, 会首先将ebp入栈, 最终恢复 8 | //G++编译出来的压栈都是4字节的(32 bits), 但是我们的nasm是16位的:-( 9 | //16位G++的内嵌汇编的iret操作的是EFLAGS,ECS,EIP; 因此, 我们要将可爱的flags,cs,ip转为32位~ 10 | //G++里内嵌汇编的iret为66cf, 内嵌的中断调用为16位int 11 | //nasm的16位iret为cf 12 | //不带局部变量的函数 13 | // 14 | #define CPP_INT_END asm volatile("pop ds;pop ebp;.BYTE 0xcf") 15 | //带局部变量的函数(ebp保存原来的esp) 16 | //leave恢复esp(用ebp做备份), 计数 +8 -6 17 | //push ebp; mov ebp, esp; esp被修改, ebp没有被改 18 | #define CPP_INT_LEAVE asm volatile("pop ds;leave;.BYTE 0xcf") 19 | #define CPP_INT_HEADER asm volatile("push ds;push ax;mov ax, cs; mov ds, ax;pop ax;") 20 | __attribute__((regparm(3))) 21 | void WriteIVT(uint16_t id,uint16_t offset,uint16_t cs){ 22 | asm volatile( 23 | "push si;push es;" 24 | "mov es, ax;" 25 | "mov si, bx;" 26 | "mov es:[si], cx;" 27 | "mov es:[si+2], dx;" 28 | "pop es;pop si;" 29 | : 30 | :"a"(0),"b"(id * 4),"c"(offset),"d"(cs) 31 | ); 32 | } 33 | 34 | __attribute__((regparm(2))) 35 | void WriteIVT(uint16_t id, void (*func)()){ 36 | uint16_t cs; 37 | asm volatile("mov ax, cs;":"=a"(cs)); 38 | WriteIVT(id,(long)func,cs); 39 | } 40 | 41 | __attribute__((regparm(1))) 42 | void ExecuteINT(uint16_t id){ 43 | uint16_t ip, cs; 44 | asm volatile( 45 | "push es;" 46 | "mov es, ax;" 47 | "mov ax, es:[bx];" 48 | "mov bx, es:[bx + 2];" 49 | "pop es;" 50 | :"=a"(ip),"=b"(cs) 51 | :"a"(0),"b"(id * 4) 52 | ); 53 | uint16_t ocs; 54 | asm volatile("mov ax, cs;":"=a"(ocs)); 55 | //不知道为什么, 一定要加下面这一句, 否则崩溃:-( 56 | PrintStr("Execute interrupt 0x"); 57 | PrintHex(id);PrintStr(NEWLINE); 58 | char addr[4]; 59 | *((uint16_t*)(addr)) = ip; 60 | *((uint16_t*)(addr+2)) = cs; 61 | asm volatile( 62 | "push es;" 63 | "mov es, ax;" 64 | "pushf;" 65 | "call far ptr es:[bx];" 66 | "pop es;" 67 | : 68 | :"a"(ocs),"b"(addr) 69 | ); 70 | } 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /lab6/include/mem_base.h: -------------------------------------------------------------------------------- 1 | #ifndef _MEM_BASE_H_ 2 | #define _MEM_BASE_H_ 3 | 4 | #include 5 | 6 | struct MemBlock{ 7 | bool used; 8 | uint16_t left, right; //[left,right) 9 | uint16_t next; 10 | }; 11 | 12 | struct MemRecord{ 13 | MemBlock *data; 14 | uint16_t MaxBlockNum; 15 | }; 16 | 17 | __attribute__((regparm(3))) 18 | void mem_init(MemRecord &mem, uint16_t left, uint16_t right){ 19 | for (uint16_t i = 0;i < mem.MaxBlockNum + 1;++i)mem.data[i].used = false; 20 | 21 | mem.data[0].used = true; 22 | mem.data[0].next = 1; 23 | mem.data[0].left = left; 24 | mem.data[0].right = left; 25 | 26 | mem.data[1].used = true; 27 | mem.data[1].left = left; 28 | mem.data[1].right = right; 29 | mem.data[1].next = mem.MaxBlockNum; 30 | 31 | mem.data[mem.MaxBlockNum].used = true; 32 | mem.data[mem.MaxBlockNum].left = right; 33 | mem.data[mem.MaxBlockNum].right = right; 34 | }; 35 | 36 | __attribute__((regparm(2))) 37 | uint16_t mem_allocate(MemRecord &mem, uint16_t needSize){ 38 | //使用最佳适应算法, 每次找最小的分区 39 | bool first = true; 40 | uint16_t blockSize = 0; 41 | uint16_t lastp = 0; 42 | uint16_t goodlastp = 0; 43 | uint16_t goodp = 0; 44 | for (uint16_t p = mem.data[0].next;p != mem.MaxBlockNum;lastp = p, p = mem.data[p].next){ 45 | uint16_t u = mem.data[p].right - mem.data[p].left; 46 | if (u < needSize)continue; 47 | if (first || u < blockSize){ 48 | first = false; 49 | goodp = p; 50 | goodlastp = lastp; 51 | blockSize = u; 52 | } 53 | } 54 | if (first)return 0xFFFF; // 无法分配 55 | uint16_t addr = mem.data[goodp].left; 56 | //从链表中删除空间 57 | if (blockSize == needSize){ 58 | //刚好删除 59 | mem.data[goodp].used = false; 60 | mem.data[goodlastp].next = mem.data[goodp].next; 61 | }else{ 62 | //大于所要申请的空间 63 | //取前面部分 64 | mem.data[goodp].left += needSize; 65 | } 66 | return addr; 67 | } 68 | 69 | __attribute__((regparm(3))) 70 | void mem_free(MemRecord &mem, uint16_t addr, uint16_t freeSize){ 71 | //释放空间 72 | uint16_t lastp = 0; 73 | uint16_t p; 74 | for (p = mem.data[lastp].next;p != mem.MaxBlockNum;lastp = p, p = mem.data[p].next){ 75 | //找到>=上个节点的right值的点 76 | if (addr >= mem.data[lastp].right && addr < mem.data[p].left)break; 77 | } 78 | //这时, addr >= memdata[lastp].right 79 | if (addr == mem.data[lastp].right && lastp != 0){ 80 | //与上一个节点融合 81 | //lastp 一定不为0 82 | if (addr + freeSize >= mem.data[p].left){ 83 | //与p节点融合 84 | if (p != mem.MaxBlockNum){ 85 | mem.data[lastp].next = mem.data[p].next; 86 | mem.data[p].used = false; 87 | mem.data[lastp].right = mem.data[p].right; 88 | }else{ 89 | mem.data[lastp].right = addr + freeSize; 90 | } 91 | }else{ 92 | mem.data[lastp].right = addr + freeSize; 93 | } 94 | }else{ 95 | //与上一个节点不融合 96 | //lastp 可能为0 97 | if (addr + freeSize >= mem.data[p].left && p != mem.MaxBlockNum){ 98 | //与p节点融合 99 | mem.data[p].left = addr; 100 | }else{ 101 | //与前后都不融合 102 | uint16_t e; 103 | for (e = 1;e < mem.MaxBlockNum;++e){ 104 | if (!mem.data[e].used)break; 105 | } 106 | mem.data[lastp].next = e; 107 | mem.data[e].used = true; 108 | mem.data[e].next = p; 109 | mem.data[e].left = addr; 110 | mem.data[e].right = addr + freeSize; 111 | } 112 | } 113 | } 114 | 115 | 116 | #endif 117 | -------------------------------------------------------------------------------- /lab6/include/memory.h: -------------------------------------------------------------------------------- 1 | #ifndef _MEMORY_H_ 2 | #define _MEMORY_H_ 3 | 4 | #include 5 | #include "mem_base.h" 6 | #include "pcb.h" 7 | 8 | struct MemAllocRecord{ 9 | bool used; 10 | uint16_t p; 11 | uint16_t size; 12 | }; 13 | 14 | #define mem_null ((void*)0xFFFF) 15 | const uint16_t MaxBlockNum = 32; 16 | const uint16_t MaxAllocNum = 256; 17 | const uint16_t SPACE_SIZE = 0x4000; // 16k, 这里用字节表示 18 | //Prog Memory 19 | MemAllocRecord mar[MaxAllocNum]; 20 | MemBlock memdata[MaxBlockNum + 1]; 21 | MemRecord memRecord; 22 | 23 | __attribute__((regparm(1))) 24 | uint16_t allocate(uint16_t needSize){ 25 | asm volatile("int 0x21;"::"a"(0x0700)); // 关闭进程切换, 更新PCB值 26 | uint16_t addr; 27 | asm volatile( 28 | "int 0x23;" 29 | :"=a"(addr) 30 | :"a"(0x0100),"c"(needSize) 31 | ); 32 | 33 | asm volatile("int 0x21;"::"a"(0x0800)); // 开启进程切换 34 | return addr; 35 | } 36 | 37 | __attribute__((regparm(2))) 38 | void free(uint16_t addr, uint16_t freeSize){ 39 | asm volatile("int 0x21;"::"a"(0x0700)); // 关闭进程切换, 更新PCB值 40 | asm volatile( 41 | "int 0x23;" 42 | : 43 | :"a"(0x0000),"b"(addr),"c"(freeSize) 44 | ); 45 | asm volatile("int 0x21;"::"a"(0x0800)); // 开启进程切换 46 | } 47 | 48 | 49 | //需要手动开启 50 | void mem_init(){ 51 | INIT_SEGMENT(); 52 | memRecord.data = memdata; 53 | memRecord.MaxBlockNum = MaxBlockNum; 54 | uint16_t runid; 55 | asm volatile("int 0x21;":"=a"(runid):"a"(0x0200)); 56 | uint16_t si, SSIZE; 57 | GetTaskAttr(runid, &_p.SIZE, si); 58 | GetTaskAttr(runid, &_p.SSIZE, SSIZE); 59 | uint16_t code = ((si + 0x100 + (1<<4) - 1) >> 4) << 4; 60 | mem_init(memRecord,code,SSIZE<<4); 61 | for (int i = 0;i < MaxAllocNum;++i)mar[i].used = false; 62 | } 63 | 64 | void * operator new(size_t size){ 65 | uint16_t p = mem_allocate(memRecord,size); 66 | if (p != 0xFFFF){ 67 | int i; 68 | for (i = 0;i < MaxAllocNum;++i){ 69 | if (!mar[i].used)break; 70 | } 71 | mar[i].used = true; 72 | mar[i].p = p; 73 | mar[i].size = size; 74 | } 75 | return (void*)(unsigned int)p; 76 | } 77 | 78 | void * operator new[](size_t size){ 79 | uint16_t p = mem_allocate(memRecord,size); 80 | if (p != 0xFFFF){ 81 | int i; 82 | for (i = 0;i < MaxAllocNum;++i){ 83 | if (!mar[i].used)break; 84 | } 85 | mar[i].used = true; 86 | mar[i].p = p; 87 | mar[i].size = size; 88 | } 89 | return (void*)(unsigned int)p; 90 | } 91 | 92 | void operator delete(void *p){ 93 | for (int i = 0;i < MaxAllocNum;++i){ 94 | if (mar[i].used && mar[i].p == (uint16_t)(unsigned long)p){ 95 | mar[i].used = false; 96 | mem_free(memRecord, mar[i].p, mar[i].size); 97 | return; 98 | } 99 | } 100 | } 101 | 102 | void operator delete[](void *p){ 103 | for (int i = 0;i < MaxAllocNum;++i){ 104 | if (mar[i].used && mar[i].p == (uint16_t)(unsigned long)p){ 105 | mar[i].used = false; 106 | mem_free(memRecord, mar[i].p, mar[i].size); 107 | return; 108 | } 109 | } 110 | } 111 | 112 | #endif 113 | -------------------------------------------------------------------------------- /lab6/include/os_sem.h: -------------------------------------------------------------------------------- 1 | #ifndef _OS_SEM_H_ 2 | #define _OS_SEM_H_ 3 | 4 | #include "pcb.h" 5 | 6 | // 汇编的cmpxchg可以原子语句 7 | // 这里我使用屏蔽进程切换的方式 8 | // Block链由PCB项记录BLOCK_NEXT 9 | 10 | struct sem{ 11 | uint8_t used; 12 | uint8_t flag; // bool 也会变为1字节 13 | int8_t count; 14 | uint8_t next; 15 | uint8_t runid; // 释放信号用 16 | }; 17 | 18 | const uint8_t MaxSemNum = 128; 19 | sem sems[MaxSemNum]; 20 | 21 | uint8_t semtemp; 22 | __attribute__((regparm(1))) 23 | void semWait(uint8_t sid){ 24 | //INIT_SEGMENT(); 25 | uint16_t ax = 1; 26 | while(1){ 27 | //原子交换 28 | asm volatile("lock xchg cs:[bx],al;":"=a"(ax):"b"(&sems[sid].flag),"a"(ax)); 29 | if ((ax&0x00FF) == 1)continue; 30 | break; 31 | } 32 | --sems[sid].count; 33 | //PrintNum(sems[sid].count,YELLOW); 34 | uint16_t runid = GetRunID(); 35 | if (sems[sid].count < 0){ 36 | //PrintStr("BLOCK"); 37 | //加入链表尾部 38 | if (sems[sid].next == 0){ 39 | //信号量阻塞队列为空 40 | sems[sid].next = (uint8_t)runid; 41 | }else{ 42 | uint8_t nex = sems[sid].next; 43 | while(1){ 44 | GetTaskAttr(nex,&_p.BLOCK_NEXT,semtemp); 45 | if (semtemp == 0)break; 46 | nex = semtemp; 47 | } 48 | SetTaskAttr(nex,&_p.BLOCK_NEXT,(uint8_t)runid); 49 | } 50 | //阻塞该进程 51 | SetTaskAttr(runid, &_p.STATE, (uint8_t)T_BLOCKED); 52 | } 53 | sems[sid].flag = 0; 54 | //防止无法及时调度, 暂时没有其他方法解决, 可能是调度程序的问题 55 | /* 56 | while(1){ 57 | if (GetTaskState(runid) != T_BLOCKED)break; 58 | }*/ 59 | Schedule; 60 | } 61 | 62 | __attribute__((regparm(1))) 63 | void semSignal(uint8_t sid){ 64 | //INIT_SEGMENT(); 65 | uint16_t ax = 1; 66 | while(1){ 67 | //原子交换 68 | asm volatile("lock xchg cs:[bx],al;":"=a"(ax):"b"(&sems[sid].flag),"a"(ax)); 69 | if ((ax&0x00FF) == 1)continue; 70 | break; 71 | } 72 | ++sems[sid].count; 73 | //PrintNum(sems[sid].count,LRED); 74 | if (sems[sid].count <= 0){ 75 | //将sems[sid].next移出 76 | uint8_t zid = sems[sid].next; 77 | GetTaskAttr(zid,&_p.BLOCK_NEXT,semtemp); 78 | SetTaskAttr(zid,&_p.BLOCK_NEXT,uint8_t(0)); 79 | sems[sid].next = semtemp; 80 | //已经移出来了 81 | SetTaskAttr(zid, &_p.STATE, (uint8_t)T_RUNNING); 82 | } 83 | sems[sid].flag = 0; 84 | } 85 | 86 | __attribute__((regparm(1))) 87 | uint8_t semCreate(int8_t count){ 88 | for (uint8_t i = 0;i < MaxSemNum;++i){ 89 | if (!sems[i].used){ 90 | sems[i].used = 1; 91 | sems[i].count = count; 92 | sems[i].next = 0; 93 | sems[i].flag = 0; 94 | sems[i].runid = GetRunID(); 95 | return i; 96 | } 97 | } 98 | return 0xFF; 99 | } 100 | 101 | __attribute__((regparm(1))) 102 | void semDel(uint8_t sid){ 103 | sems[sid].used = false; 104 | } 105 | 106 | 107 | __attribute__((regparm(1))) 108 | void semRelease(uint8_t runid){ 109 | for (uint8_t i = 0;i < MaxSemNum;++i){ 110 | if (sems[i].used && sems[i].runid == runid){ 111 | sems[i].used = false; 112 | } 113 | } 114 | } 115 | 116 | void INIT_SEM(){ 117 | for (int i = 0;i < MaxSemNum;++i){ 118 | sems[i].used = 0; 119 | } 120 | } 121 | 122 | #endif 123 | -------------------------------------------------------------------------------- /lab6/include/port.h: -------------------------------------------------------------------------------- 1 | #ifndef _PORT_H_ 2 | #define _PORT_H_ 3 | /* 4 | ;22H进程, 进程通信 5 | 6 | ;ah = 00h 读 7 | ;ah = 01h 写 8 | ;ah = 02h 信号量设置(bh=0, 清零; bh=1, 加1; bh=2, 减1; bh=3, 设置为bl值) 9 | ;ah = 03h 设置端口 10 | ;ah = 04h 关闭端口 11 | ;ah = 05h 只返回信号量 12 | ;al = 端口值 13 | ;基地址bx, 缓存大小cx, 段地址dx 14 | ;返回信号量(ax) 15 | */ 16 | #include "defines.h" 17 | 18 | __attribute__((regparm(3))) 19 | void SetPort(uint8_t portID, void* varAddr, uint16_t size){ 20 | uint16_t cs; 21 | asm volatile("mov ax,cs;":"=a"(cs)); 22 | asm volatile("int 0x22;" 23 | : 24 | :"a"((3 << 8) | portID), "b"(varAddr), "c"(size), "d"(cs) 25 | ); 26 | } 27 | 28 | __attribute__((regparm(3))) 29 | uint8_t ReadPort(uint8_t portID, void* varAddr, uint16_t size){ 30 | uint16_t cs; 31 | uint8_t v; 32 | asm volatile("mov ax,cs;":"=a"(cs)); 33 | asm volatile("int 0x22;" 34 | :"=a"(v) 35 | :"a"((0 << 8) | portID), "b"(varAddr), "c"(size), "d"(cs) 36 | ); 37 | return v; 38 | } 39 | 40 | __attribute__((regparm(3))) 41 | void WritePort(uint8_t portID, void* varAddr, uint16_t size){ 42 | uint16_t cs; 43 | asm volatile("mov ax,cs;":"=a"(cs)); 44 | asm volatile("int 0x22;" 45 | : 46 | :"a"((1 << 8) | portID), "b"(varAddr), "c"(size), "d"(cs) 47 | ); 48 | } 49 | 50 | 51 | __attribute__((regparm(2))) 52 | void SetPortMsgV(uint8_t portID, uint8_t v){ 53 | uint16_t cs; 54 | asm volatile("mov ax,cs;":"=a"(cs)); 55 | asm volatile("int 0x22;" 56 | : 57 | :"a"((2<<8) | portID), "b"((3<<8) | v) 58 | ); 59 | } 60 | 61 | 62 | __attribute__((regparm(1))) 63 | uint8_t GetPortMsgV(uint8_t portID){ 64 | uint8_t v; 65 | asm volatile("int 0x22;" 66 | :"=a"(v) 67 | :"a"((5<<8) | portID) 68 | ); 69 | return v; 70 | } 71 | #endif 72 | -------------------------------------------------------------------------------- /lab6/include/sem.h: -------------------------------------------------------------------------------- 1 | #ifndef _SEM_H_ 2 | #define _SEM_H_ 3 | #include 4 | 5 | __attribute__((regparm(1))) 6 | void semWait(uint8_t sid){ 7 | uint16_t ax = 0x0100 | sid; 8 | /* 9 | asm volatile( 10 | "pushf;" 11 | "call far ptr cs:[bx];" 12 | : 13 | :"a"(ax),"b"(0x25 * 4) 14 | ); 15 | */ 16 | asm volatile("int 0x25"::"a"(ax)); 17 | } 18 | 19 | __attribute__((regparm(1))) 20 | void semSignal(uint8_t sid){ 21 | uint16_t ax = 0x0200 | sid; 22 | /* 23 | asm volatile( 24 | "pushf;" 25 | "call far ptr cs:[bx];" 26 | : 27 | :"a"(ax),"b"(0x25 * 4) 28 | ); 29 | */ 30 | 31 | asm volatile("int 0x25"::"a"(ax)); 32 | } 33 | 34 | 35 | __attribute__((regparm(1))) 36 | uint8_t semCreate(int8_t count){ 37 | uint16_t ax = 0x0000 | (uint16_t)count; 38 | uint8_t sid; 39 | 40 | /* 41 | asm volatile( 42 | "pushf;" 43 | "call far ptr cs:[bx];" 44 | :"=a"(sid) 45 | :"a"(ax),"b"(0x25 * 4) 46 | ); 47 | */ 48 | 49 | asm volatile("int 0x25":"=a"(sid):"a"(ax)); 50 | return sid; 51 | } 52 | 53 | __attribute__((regparm(1))) 54 | void semDel(uint8_t sid){ 55 | uint16_t ax = 0x0400 | sid; 56 | asm volatile("int 0x25"::"a"(ax)); 57 | } 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /lab6/include/string.h: -------------------------------------------------------------------------------- 1 | #ifndef _STRING_H_ 2 | #define _STRING_H_ 3 | 4 | #include "defines.h" 5 | 6 | __attribute__((regparm(1))) 7 | int strlen(const char *s){ 8 | int i = 0; 9 | while(*(s++))i++; 10 | return i; 11 | } 12 | 13 | __attribute__((regparm(2))) 14 | int strcmp(const char *astr,const char *bstr){ 15 | // = 0 16 | // < -1 17 | // > 1 18 | while ((*astr) && (*bstr)){ 19 | if (*astr != *bstr){ 20 | if (*astr < *bstr)return -1; 21 | return 1; 22 | } 23 | ++astr; 24 | ++bstr; 25 | } 26 | return (*astr) - (*bstr); 27 | } 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /lab6/include/thread.h: -------------------------------------------------------------------------------- 1 | #ifndef _THREAD_H_ 2 | #define _THREAD_H_ 3 | 4 | #include "pcb.h" 5 | #include "memory.h" 6 | 7 | struct thread_t{ 8 | uint16_t tid; 9 | }; 10 | 11 | uint8_t parentID; // 使用引用要放外面? 12 | __attribute__((regparm(3))) 13 | uint8_t thread_create(thread_t *t, __attribute__((regparm(1)))void* (*func)(void*), void *attr){ 14 | ScheduleOFF; 15 | Schedule; 16 | INIT_SEGMENT(); 17 | uint16_t runid = GetRunID(); 18 | LoadPCB(runid); // note:IP! 19 | if (_p.KIND == K_THREAD){ 20 | void *result = func(attr); // 执行函数 21 | SetTaskState(runid, T_DEAD); 22 | GetTaskAttr(runid, &_p.PARENT_ID, parentID); 23 | SetTaskAttr(parentID, &_p.STATE, uint8_t(T_RUNNING)); // 让父亲返回RUNNING态 24 | ScheduleON; 25 | asm volatile("mov ax, bx;"::"b"((uint16_t)(unsigned long)result)); 26 | Schedule; 27 | while(1){} 28 | return 0; // 子进程返回0 29 | } 30 | uint8_t newID = FindEmptyPCB(); 31 | uint16_t addrseg = allocate(0x10); 32 | if (addrseg == 0xFFFF){ 33 | ScheduleON; 34 | return 0xFF; 35 | } 36 | //[ds:si] -> [es:di] 37 | asm volatile("push ds;push si;push es;push di;" 38 | "mov ds,ax;" 39 | "mov es,dx;" 40 | "xor si,si;" 41 | "xor di,di;" 42 | "cld;" 43 | "COPY_STACK:;" 44 | "movsw;movsw;movsw;movsw;" 45 | "movsw;movsw;movsw;movsw;" 46 | "loop COPY_STACK;" 47 | "pop di;pop es;pop si;pop ds;" 48 | : 49 | :"a"(_p.SEG),"d"(addrseg),"c"(0x10) 50 | ); 51 | 52 | // 注意, ID与RunID类型是不同的,db和dw 53 | _p.ID = newID; 54 | _p.SS = addrseg; 55 | _p.SEG = addrseg; 56 | _p.SSIZE = 0x10; 57 | _p.PARENT_ID = runid; 58 | _p.KIND = K_THREAD; 59 | t->tid = newID; 60 | WritePCB(newID); 61 | INC_RunNum; 62 | ScheduleON; 63 | return newID; 64 | } 65 | 66 | 67 | __attribute__((regparm(2))) 68 | uint8_t thread_join(thread_t _t, void **_thread_retn){ 69 | INIT_SEGMENT(); 70 | uint16_t tid = _t.tid; 71 | uint16_t runid = GetRunID(); 72 | while(1){ 73 | if (GetTaskState(tid) == T_DEAD)break; 74 | SetTaskAttr(runid, &_p.STATE, uint8_t(T_BLOCKED)); // 设置自己为阻塞态 75 | Schedule; 76 | } 77 | uint16_t ax; 78 | GetTaskAttr(tid, &_p.AX, ax); 79 | //SetTaskAttr(tid, &_p.KIND, (uint8_t)K_PROG); // 设为普通程序, 并杀死 80 | if (_thread_retn)*_thread_retn = (void*)(long)ax; 81 | return tid; 82 | } 83 | #endif 84 | -------------------------------------------------------------------------------- /lab6/include/version.h: -------------------------------------------------------------------------------- 1 | #define RELEASE_TIMES 846 2 | -------------------------------------------------------------------------------- /lab6/pic/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab6/pic/1.png -------------------------------------------------------------------------------- /lab6/pic/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab6/pic/2.png -------------------------------------------------------------------------------- /lab6/pic/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab6/pic/3.png -------------------------------------------------------------------------------- /lab6/report/14348134吴侃lab6.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab6/report/14348134吴侃lab6.docx -------------------------------------------------------------------------------- /lab6/report/14348134吴侃lab6.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab6/report/14348134吴侃lab6.pdf -------------------------------------------------------------------------------- /lab6/source/alpha.cpp: -------------------------------------------------------------------------------- 1 | #include "fork.h" 2 | #include "io.h" 3 | 4 | char str[64] = "WhAlE aNd MoBuLA"; 5 | int main(){ 6 | PrintStr(str,LBLUE); 7 | PrintStr(NEWLINE); 8 | if (fork()){ 9 | //大写 10 | asm volatile( 11 | "mov dx,cs;" 12 | "int 0x24;" 13 | : 14 | :"a"(0x0100),"b"(str) 15 | :"dx" 16 | ); 17 | PrintStr(str,RED); 18 | }else{ 19 | //小写 20 | asm volatile( 21 | "mov dx,cs;" 22 | "int 0x24;" 23 | : 24 | :"a"(0x0000),"b"(str) 25 | :"dx" 26 | ); 27 | PrintStr(str,LGREEN); 28 | } 29 | PrintStr(NEWLINE); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /lab6/source/bpb.cpp: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | 3 | #pragma pack (1) // 按1字节对齐 4 | struct FAT12Header{ 5 | dw jmpShort;//BS_jmpBOOT 一个短跳转指令 6 | db nop; 7 | db BS_OEMName[8]; // 厂商名 8 | dw BPB_BytesPerSec; //每扇区字节数(Bytes/Sector) 0x200 9 | db BPB_SecPerClus; //每簇扇区数(Sector/Cluster) 0x1 10 | dw BPB_ResvdSecCnt; //Boot记录占用多少扇区 ox1 11 | db BPB_NumFATs; //共有多少FAT表 0x2 12 | dw BPB_RootEntCnt; //根目录区文件最大数 0xE0 13 | dw BPB_TotSec16; //扇区总数 0xB40[2*80*18] 14 | db BPB_Media; //介质描述符 0xF0 15 | dw BPB_FATSz16; //每个FAT表所占扇区数 0x9 16 | dw BPB_SecPerTrk; //每磁道扇区数(Sector/track) 0x12 17 | dw BPB_NumHeads; //磁头数(面数) 0x2 18 | dd BPB_HiddSec; //隐藏扇区数 0 19 | dd BPB_TotSec32; //如果BPB_TotSec16=0,则由这里给出扇区数 0 20 | db BS_DrvNum; //INT 13H的驱动器号 0 21 | db BS_Reserved1; //保留,未使用 0 22 | db BS_BootSig; //扩展引导标记(29h) 0x29 23 | dd BS_VolID; //卷序列号 0 24 | db BS_VolLab[11]; //卷标 'wkcn' 25 | db BS_FileSysType[8]; //文件系统类型 'FAT12' 26 | db other[448]; //引导代码及其他数据 引导代码(剩余空间用0填充) 27 | dw _55aa; //第510字节为0x55,第511字节为0xAA 0xAA55 28 | }; 29 | 30 | 31 | __attribute__((regparm(3))) 32 | void ReadFloppy(uint16_t sectorID, uint8_t sectorNum, char *data){ 33 | const uint16_t SecPerTrk = 18; 34 | //const uint16_t BytsPerSec = 512; 35 | uint8_t y = sectorID / SecPerTrk; 36 | uint8_t z = sectorID % SecPerTrk; 37 | uint8_t cl = z + 1; // 起始扇区号 38 | uint8_t ch = y >> 1; // 柱面号 39 | uint8_t dh = y & 1; // 磁头号 40 | uint8_t dl = 0; // 驱动器号, 0表示软盘A 41 | uint8_t ah = 2; // 功能号 42 | uint8_t al = sectorNum; // 读扇区数 43 | asm volatile( 44 | "push es;" 45 | "push ax;" 46 | "mov ax, ds;" 47 | "mov es, ax;" 48 | "pop ax;" 49 | "int 0x13;" 50 | "pop es;" 51 | : 52 | :"a"((ah<<8)|al),"b"(data),"c"((ch<<8)|cl),"d"((dh<<8)|dl) 53 | ); 54 | } 55 | 56 | 57 | FAT12Header header; 58 | int main(){ 59 | ReadFloppy(0,1,(char*)&header); 60 | 61 | PrintStr("jmpShort dw 0x"); 62 | PrintHex((header.jmpShort >> 8) & 0xFF); 63 | PrintHex((header.jmpShort) & 0xFF); 64 | PrintStr(NEWLINE); 65 | PrintStr("nop"); 66 | PrintStr(NEWLINE); 67 | PrintStr("OEMName db \""); 68 | PrintStrN(header.BS_OEMName,8); 69 | PrintChar('\"'); 70 | PrintStr(NEWLINE); 71 | 72 | PrintStr("BytesPerSec dw "); 73 | PrintNum(header.BPB_BytesPerSec); 74 | PrintStr(NEWLINE); 75 | 76 | PrintStr("SecPerClus db "); 77 | PrintNum(header.BPB_SecPerClus); 78 | PrintStr(NEWLINE); 79 | 80 | PrintStr("ResvdSecCnt dw "); 81 | PrintNum(header.BPB_ResvdSecCnt); 82 | PrintStr(NEWLINE); 83 | 84 | PrintStr("NumFATs db "); 85 | PrintNum(header.BPB_NumFATs); 86 | PrintStr(NEWLINE); 87 | 88 | PrintStr("RootEntCnt dw "); 89 | PrintNum(header.BPB_RootEntCnt); 90 | PrintStr(NEWLINE); 91 | 92 | PrintStr("TotSec16 dw "); 93 | PrintNum(header.BPB_TotSec16); 94 | PrintStr(NEWLINE); 95 | 96 | PrintStr("Media db 0x"); 97 | PrintHex(header.BPB_Media); 98 | PrintStr(NEWLINE); 99 | 100 | PrintStr("FatSz16 dw "); 101 | PrintNum(header.BPB_FATSz16); 102 | PrintStr(NEWLINE); 103 | 104 | PrintStr("SecPerTrk dw "); 105 | PrintNum(header.BPB_SecPerTrk); 106 | PrintStr(NEWLINE); 107 | 108 | PrintStr("NumHeads dw "); 109 | PrintNum(header.BPB_NumHeads); 110 | PrintStr(NEWLINE); 111 | 112 | PrintStr("HiddSec dd 0x"); 113 | PrintNum(header.BPB_HiddSec); 114 | PrintStr(NEWLINE); 115 | 116 | PrintStr("TotSec32 dd 0x"); 117 | PrintNum(header.BPB_TotSec32); 118 | PrintStr(NEWLINE); 119 | 120 | return 0; 121 | } 122 | -------------------------------------------------------------------------------- /lab6/source/bs.cpp: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | #include "disk.h" 3 | 4 | FAT12Header header; 5 | int main(){ 6 | 7 | ReadFloppy(0,1,&header); 8 | 9 | PrintStr("DrvNum db "); 10 | PrintNum(header.BS_DrvNum); 11 | PrintStr(NEWLINE); 12 | 13 | PrintStr("Reserved1 db "); 14 | PrintNum(header.BS_Reserved1); 15 | PrintStr(NEWLINE); 16 | 17 | PrintStr("BootSig db 0x"); 18 | PrintHex(header.BS_BootSig); 19 | PrintStr(NEWLINE); 20 | 21 | PrintStr("VolID db "); 22 | PrintNum(header.BS_VolID); 23 | PrintStr(NEWLINE); 24 | 25 | PrintStr("VolLab db \""); 26 | PrintStrN(header.BS_VolLab,11); 27 | PrintChar('\"'); 28 | PrintStr(NEWLINE); 29 | 30 | PrintStr("FileSysType db \""); 31 | PrintStrN(header.BS_FileSysType,8); 32 | PrintChar('\"'); 33 | PrintStr(NEWLINE); 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /lab6/source/counter.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | string head = "#define RELEASE_TIMES "; 6 | string filename = "include/version.h"; 7 | int main(){ 8 | fstream fin(filename.c_str()); 9 | fin.seekg(head.size()); 10 | int v; 11 | fin >> v; 12 | ++v; 13 | cout << head << v << endl; 14 | fin.seekp(0,ios::beg); 15 | fin << head << v << endl; 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /lab6/source/fork1.cpp: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | #include "fork.h" 3 | 4 | int main(){ 5 | if (fork() == 0){ 6 | for (int i = 0;i < 20;++i){ 7 | PrintChar('.'); 8 | } 9 | }else{ 10 | if (fork() == 0){ 11 | for (int i = 0;i < 20;++i){ 12 | PrintChar('o'); 13 | } 14 | }else{ 15 | for (int i = 0;i < 20;++i){ 16 | PrintChar('x'); 17 | } 18 | } 19 | } 20 | PrintStr(NEWLINE); 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /lab6/source/fork2.cpp: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | #include "fork.h" 3 | 4 | ostream cout; 5 | int main(){ 6 | int i=0; 7 | for(i=0;i<3;i++){ 8 | uint8_t fpid=fork(); 9 | if(fpid==0) 10 | PrintStr("son", YELLOW); 11 | else 12 | PrintStr("FATHER",LGREEN); 13 | PrintStr(NEWLINE); 14 | } 15 | return 0; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /lab6/source/fruit.cpp: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | #include "thread.h" 3 | #include "sem.h" 4 | 5 | uint16_t count = 0; 6 | uint8_t sid; 7 | uint16_t fid[2]; 8 | bool useSem = true; 9 | uint16_t total = 50; 10 | 11 | __attribute__((regparm(1))) 12 | void * GiveFruit(void *p){ 13 | for (int i = 0;i < total / 2;++i){ 14 | if(useSem)semWait(sid); 15 | PrintNum(*(uint16_t*)(p), LBLUE);// 进入 16 | uint16_t old; 17 | old = count; 18 | for (uint16_t w=0;w<0xFFFF;++w){ 19 | for (uint16_t ww=0;ww<0xFF;++ww){ 20 | for (uint16_t www=0;www<0x1;++www){ 21 | } 22 | } 23 | } 24 | count = old + 1; 25 | PrintNum(count,RED); // 数字 26 | PrintNum(*(uint16_t*)(p),LGREEN); // 出来 27 | if(useSem)semSignal(sid); 28 | } 29 | return 0; 30 | } 31 | 32 | int main(){ 33 | thread_t tid[2]; 34 | sid = semCreate(1); 35 | fid[0] = 0; 36 | fid[1] = 1; 37 | 38 | thread_create(&tid[0],GiveFruit,&fid[0]); 39 | thread_create(&tid[1],GiveFruit,&fid[1]); 40 | thread_join(tid[0],0); 41 | thread_join(tid[1],0); 42 | PrintStr("I have "); 43 | PrintNum(count); 44 | PrintStr(" fruits, I should have "); 45 | PrintNum(total); 46 | PrintStr(NEWLINE); 47 | 48 | PrintStr("I don't use sem!\r\n",LGREEN); 49 | count = 0; 50 | useSem = 0; 51 | thread_create(&tid[0],GiveFruit,&fid[0]); 52 | thread_create(&tid[1],GiveFruit,&fid[1]); 53 | thread_join(tid[0],0); 54 | thread_join(tid[1],0); 55 | PrintStr("I have "); 56 | PrintNum(count); 57 | PrintStr(" fruits, I should have "); 58 | PrintNum(total); 59 | PrintStr(NEWLINE); 60 | 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /lab6/source/header.asm: -------------------------------------------------------------------------------- 1 | BITS 16 2 | 3 | [global _start] 4 | [extern main] 5 | 6 | _start: 7 | push word 0 ; 由于G++的ret是32位的, 这里补0 8 | call main 9 | ;调用int 20h 10 | xor ax, ax 11 | mov es, ax 12 | mov di, 20h * 4 13 | pushf 14 | call far [es:di] 15 | jmp $ 16 | -------------------------------------------------------------------------------- /lab6/source/help.cpp: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | 3 | const char *HELP_INFO = "\ 4 | Input a 1~5 for parallel running. A stream nums for serial running \n\r\ 5 | Commands:\n\r\ 6 | r Go to look user processes\n\r\ 7 | ls list all programs\n\r\ 8 | cls Clear Screen\n\r\ 9 | top View all running processes\n\r\ 10 | wake Wake a process, ex: wake 1\n\r\ 11 | suspend Suspend a process, ex: suspend 2\n\r\ 12 | pr Set the priority of a task ex: pr [pid] [priority]\n\r\ 13 | kill Kill a process, ex: kill 3\n\r\ 14 | killall Kill all Processes\n\r\ 15 | uname Show os info\n\r\ 16 | Keys:\n\r\ 17 | Esc Back to Shell but not kill processes\n\r\ 18 | Ctrl+C Clear Screen\n\r\ 19 | Ctrl+Z Back to Shell and kill all processes\n\r\ 20 | "; 21 | 22 | int main(){ 23 | PrintStr(HELP_INFO,WHITE); 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /lab6/source/kan.asm: -------------------------------------------------------------------------------- 1 | ;My Name 2 | ;Jackie Wu (Wu Kan) 3 | ;14348134 4 | 5 | org 100H 6 | ;org 7c00h 7 | outDelay equ 40000 8 | inDelay equ 500 9 | 10 | ;set data segment 11 | mov ax,cs 12 | mov ds,ax 13 | 14 | ;text window 15 | ;25 * 80 16 | mov ax,0B800h 17 | mov es,ax 18 | 19 | %macro SETMEM 2 20 | mov ax,%2 21 | mov [%1],ax 22 | %endmacro 23 | 24 | START: 25 | call DELAY 26 | call SHOWINFO 27 | call DELAY 28 | 29 | SETMEM pos,1405H 30 | SETMEM vel,0FF01H 31 | mov cx,8 32 | call LINE 33 | 34 | SETMEM pos,1109H 35 | SETMEM vel,0001H 36 | mov cx,14 37 | call LINE 38 | 39 | SETMEM pos,1705H 40 | SETMEM vel,0001H 41 | mov cx,7 42 | call LINE 43 | 44 | SETMEM pos,1705H 45 | SETMEM vel,0100H 46 | mov cx,10 47 | call LINE 48 | 49 | SETMEM vel,0001H 50 | mov cx,7 51 | call LINE 52 | 53 | SETMEM pos,170BH 54 | SETMEM vel,0100H 55 | mov cx,10 56 | call LINE 57 | 58 | SETMEM pos,170DH 59 | SETMEM vel,0001H 60 | mov cx,8 61 | call LINE 62 | 63 | SETMEM pos,1615H 64 | SETMEM vel,0FF01H 65 | mov cx,2 66 | call LINE 67 | 68 | SETMEM pos,1B0DH 69 | SETMEM vel,0001H 70 | mov cx,10 71 | call LINE 72 | 73 | SETMEM pos,1F0DH 74 | SETMEM vel,0001H 75 | mov cx,9 76 | call LINE 77 | 78 | SETMEM vel,0100H 79 | mov cx,4 80 | call LINE 81 | 82 | SETMEM vel,00FFH 83 | mov cx,2 84 | call LINE 85 | 86 | call DELAY 87 | call DELAY 88 | call DELAY 89 | call DELAY 90 | call DELAY 91 | mov ax,3 92 | int 10h 93 | jmp START 94 | 95 | LINE: 96 | ;cx is the len of line 97 | LINELOOP: 98 | call DELAY 99 | call SHOW 100 | call MOVEPOS 101 | loop LINELOOP 102 | ret 103 | 104 | SHOWINFO: 105 | mov cx,[msgLen] 106 | 107 | mov si,message 108 | 109 | mov di, (1*80 + 1) * 2 110 | 111 | printChar: 112 | mov al,[si] 113 | inc si 114 | mov ah,07h 115 | mov [es:di],ax 116 | add di,2 117 | loop printChar 118 | ret 119 | 120 | DELAY: 121 | push cx 122 | mov cx, outDelay 123 | LOOP1: 124 | mov ax, inDelay 125 | LOOP2: 126 | dec ax 127 | jg LOOP2 128 | loop LOOP1 129 | pop cx 130 | 131 | ret 132 | 133 | MOVEPOS: 134 | mov ax,[pos] 135 | mov bx,[vel] 136 | add ah,bh 137 | add al,bl 138 | mov [pos],ax 139 | ret 140 | 141 | SHOW: 142 | push cx 143 | mov bx,[pos] 144 | mov ax,0 145 | mov al,bl 146 | mov dx,80 147 | mul dx 148 | mov dx,0 149 | mov dl,bh 150 | add ax,dx 151 | mov cx,2 152 | mul cx 153 | mov bx, ax 154 | 155 | mov al,[char] 156 | inc al 157 | cmp al,'Z' 158 | jna LESSZ 159 | mov al,'A' 160 | LESSZ: 161 | mov [char],al 162 | mov ah,[color] 163 | and ah,0Fh 164 | inc byte[color] 165 | mov [es:bx],ax 166 | pop cx 167 | ret 168 | 169 | DATA: 170 | message db "My Name is" 171 | msgLen dw $-message 172 | 173 | pos dw 0000h 174 | vel dw 0000h 175 | char db 'a' 176 | color db 09H 177 | 178 | times 510-($-$$) db 0 179 | dw 0xaa55 180 | -------------------------------------------------------------------------------- /lab6/source/letter.cpp: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | #include "thread.h" 3 | 4 | char str[80]="129djwqhdsajd128dw9i39ie93i8494urjoiew98kdkd"; 5 | int LetterNr=0; 6 | 7 | __attribute__((regparm(1))) 8 | void* Count(void *){ 9 | for (int i = 0;str[i];++i){ 10 | if (str[i] >= 'a' && str[i] <= 'z')LetterNr++; 11 | } 12 | return (void*)LetterNr; 13 | } 14 | 15 | int main(){ 16 | thread_t tid; 17 | thread_create(&tid, Count, 0); 18 | thread_join(tid, 0); 19 | PrintStr("#Alpha of Str: "); 20 | PrintNum(LetterNr); 21 | PrintStr(NEWLINE); 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /lab6/source/linker_100.ld: -------------------------------------------------------------------------------- 1 | ENTRY(main); 2 | SECTIONS 3 | { 4 | . = 0x100; 5 | .text : AT(0x100) 6 | { 7 | _text = .; 8 | *(.text); 9 | _text_end = .; 10 | } 11 | .data : 12 | { 13 | _data = .; 14 | *(.bss); 15 | *(.bss*); 16 | *(.data); 17 | *(.rodata*); 18 | *(COMMON) 19 | _data_end = .; 20 | } 21 | /DISCARD/ : 22 | { 23 | *(.note*); 24 | *(.iplt*); 25 | *(.igot*); 26 | *(.rel*); 27 | *(.comment); 28 | /* add any unwanted sections spewed out by your version of gcc and flags here */ 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /lab6/source/ls.cpp: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | #include "disk.h" 3 | 4 | char buf[512]; 5 | Entry e; 6 | 7 | const char Months[12][4] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}; 8 | 9 | __attribute__((regparm(1))) 10 | void PrintDate(uint16_t date){ 11 | //Month 12 | uint8_t month = (date >> 5) & 0xF; 13 | PrintStr(Months[month - 1]); 14 | PrintChar('.'); 15 | uint8_t day = (date) & 0x1F; 16 | PrintNum(day); 17 | PrintChar(','); 18 | uint16_t year = uint16_t((date >> 9) & 0x7F) + 1980; 19 | PrintNum(year); 20 | } 21 | 22 | __attribute__((regparm(1))) 23 | void Print2Num(int num){ 24 | PrintChar(num / 10 + '0'); 25 | PrintChar(num % 10 + '0'); 26 | } 27 | 28 | __attribute__((regparm(2))) 29 | void PrintTime(uint16_t t,uint8_t offset){ 30 | uint8_t second = (t & 0x1F) * 2; 31 | uint8_t minute = ((t>>5) & 0x3F); 32 | uint8_t hour = (((t>>11) & 0x1F) + offset)%24; 33 | Print2Num(hour); 34 | PrintChar(':'); 35 | Print2Num(minute); 36 | PrintChar(':'); 37 | Print2Num(second); 38 | } 39 | 40 | char dbuf[1024]; 41 | __attribute__((regparm(1))) 42 | uint16_t GetNextCluster(uint16_t u){ 43 | //get fat 44 | int t = u * 3 / 2; 45 | int p = t / 512; 46 | int o = t % 512; 47 | ReadFloppy(1 + p,2,dbuf); 48 | //uint16_t w = ((buf[o+1]&0xFF) << 8) | (buf[o]&0xFF); 49 | //注意位扩展:-( 50 | uint16_t w = *(uint16_t*)(dbuf + o); 51 | if (u % 2 == 0){ 52 | w &= 0xFFF; 53 | }else{ 54 | w = (w >> 4) & 0xFFF; 55 | } 56 | return w; 57 | } 58 | 59 | __attribute__((regparm(1))) 60 | void PrintClusters(uint16_t u){ 61 | PrintNum(u); 62 | u = GetNextCluster(u); 63 | for(int i = 0;i < 5 &&(!(u >= 0xFF8));++i){ 64 | PrintChar(','); 65 | PrintNum(u); 66 | u = GetNextCluster(u); 67 | } 68 | if (!(u >= 0xFF8)){ 69 | PrintStr(",..."); 70 | } 71 | } 72 | int main(){ 73 | 74 | bool first = true; 75 | for (int i = 19;i < 19 + 14;++i){ 76 | ReadFloppy(i,1,buf); 77 | for (int j = 0;j < 512/32;++j){ 78 | for (int k = 0;k < 32;++k){ 79 | *(((char*)&e) + k) = buf[k + j*32]; 80 | } 81 | if (e.DIR_Name[10] == 0)continue; 82 | if (first){ 83 | first = false; 84 | PrintStr("Filename Size Date Time(UTC+8) Clusters",LBLUE); 85 | PrintStr(NEWLINE); 86 | } 87 | //Print Name 88 | int count = 0; 89 | for (int i = 0;i < 8;++i){ 90 | if(e.DIR_Name[i] && e.DIR_Name[i] != ' '){ 91 | PrintChar(e.DIR_Name[i]); 92 | ++count; 93 | } 94 | else break; 95 | } 96 | PrintChar('.'); 97 | for (int i = 8;i < 11;++i){ 98 | if(e.DIR_Name[i] && e.DIR_Name[i] != ' '){ 99 | PrintChar(e.DIR_Name[i]); 100 | ++count; 101 | } 102 | else break; 103 | } 104 | for (int i = count;i < 12;++i)PrintChar(' '); 105 | count = PrintNum(e.DIR_FileSize); 106 | for(int i = count;i < 6;++i)PrintChar(' '); 107 | PrintDate(e.LAST_WrtDate); 108 | PrintChar(' '); 109 | //使用东八区时间 110 | PrintTime(e.LAST_WrtTime, 8); 111 | //Print Clusters 112 | PrintStr(" "); 113 | PrintClusters(e.DIR_FstClus); 114 | PrintStr(NEWLINE); 115 | } 116 | } 117 | 118 | return 0; 119 | } 120 | -------------------------------------------------------------------------------- /lab6/source/mat.cpp: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | #include "thread.h" 3 | 4 | const int M = 3; 5 | const int K = 2; 6 | const int N = 3; 7 | const int NUM_THREADS = M * N; 8 | int A[M][K]={{1,4},{2,5},{3,6}}; 9 | int B[K][N]={{8,7,6},{5,4,3}}; 10 | int C[M][N]; 11 | 12 | struct RC{ 13 | int r,c; 14 | }; 15 | 16 | RC data[NUM_THREADS]; 17 | 18 | __attribute__((regparm(1))) 19 | void* CalcOneElem(void* i){ 20 | RC rc = *(RC*)i; 21 | int r = rc.r; 22 | int c = rc.c; 23 | C[r][c] = 0; 24 | for (int i = 0;i < K;++i){ 25 | C[r][c] += A[r][i] * B[i][c]; 26 | } 27 | return 0; 28 | } 29 | 30 | 31 | __attribute__((regparm(3))) 32 | void PrintMat(int *a, int r, int c){ 33 | for (int _r = 0;_r < r;++_r){ 34 | PrintStr(" "); 35 | for (int _c = 0;_c < c;++_c){ 36 | PrintNum(a[_r * c + _c]); 37 | PrintChar(' '); 38 | } 39 | PrintStr(NEWLINE); 40 | } 41 | } 42 | 43 | int main(){ 44 | thread_t tid[NUM_THREADS]; 45 | for (int i = 0;i < M;++i){ 46 | for (int j = 0;j < N;++j){ 47 | int id = i * N + j; 48 | data[id].r = i; 49 | data[id].c = j; 50 | thread_create(&tid[id],CalcOneElem,&data[id]); 51 | } 52 | } 53 | //等待所有线程结束 54 | for (int i = 0;i < NUM_THREADS;++i){ 55 | thread_join(tid[i],0); 56 | } 57 | PrintMat((int*)A,M,K); 58 | PrintStr(" X\r\n",GREEN); 59 | PrintMat((int*)B,K,N); 60 | PrintStr("The result is: \r\n"); 61 | PrintMat((int*)C,M,N); 62 | PrintStr(NEWLINE); 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /lab6/source/testint.asm: -------------------------------------------------------------------------------- 1 | org 100h 2 | 3 | int 33h 4 | int 34h 5 | int 35h 6 | int 36h 7 | ;int 21h 8 | 9 | int 20h 10 | jmp $ 11 | -------------------------------------------------------------------------------- /lab6/source/testnew.cpp: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | #include "memory.h" 3 | 4 | int main(){ 5 | mem_init(); 6 | int *a = new int; 7 | if (a != mem_null){ 8 | *a = 10; 9 | PrintNum((uint16_t)(unsigned long)a,RED); 10 | PrintNum(*a); 11 | delete a; 12 | a = new int; 13 | *a = 30; 14 | PrintNum((uint16_t)(unsigned long)a,GREEN); 15 | PrintNum(*a); 16 | PrintStr(NEWLINE); 17 | delete a; 18 | a = new int[100]; 19 | if (a == mem_null){ 20 | PrintStr("Lack of Memory!"); 21 | return 0; 22 | } 23 | a[0] = 1; 24 | a[1] = 1; 25 | for (int i = 2;i < 20;++i){ 26 | a[i] = a[i-1] + a[i-2]; 27 | } 28 | for (int i = 0;i < 20;++i){ 29 | PrintNum(a[i]); 30 | PrintChar(','); 31 | } 32 | }else{ 33 | PrintStr("Lack of Memory!"); 34 | } 35 | PrintStr(NEWLINE); 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /lab6/source/testport.cpp: -------------------------------------------------------------------------------- 1 | #include "port.h" 2 | 3 | char GoodJob[32] = "GoodJob!"; 4 | int main(){ 5 | WritePort(5,GoodJob,32); 6 | SetPortMsgV(5,1); 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /lab6/source/testst.cpp: -------------------------------------------------------------------------------- 1 | void havepar(){ 2 | int a = 2; 3 | int b = a + 3; 4 | } 5 | 6 | void ww(){ 7 | havepar(); 8 | } 9 | -------------------------------------------------------------------------------- /lab6/source/wkcn1.asm: -------------------------------------------------------------------------------- 1 | ;Running Ball 2 | ;Jackie Wu (Wu Kan) 3 | ;14348134 4 | ;wkcn@live.cn 5 | 6 | ;totalDelay = outDelay * inDelay 7 | org 100H 8 | outDelay equ 40000 9 | inDelay equ 1000 10 | 11 | ;80 x 25 12 | SCREEN_X equ 80 13 | SCREEN_Y equ 25 14 | ;Ball in this Rect 15 | MIN_X equ 40 16 | MIN_Y equ 0 17 | MAX_X equ 80 18 | MAX_Y equ 13 19 | 20 | ;set data segment 21 | ;mov ax,07c0h 22 | mov ax,cs 23 | mov ds,ax 24 | 25 | ;text window 26 | ;25 * 80 27 | mov ax,0B800h 28 | mov es,ax 29 | 30 | 31 | %macro SINGLE 4 32 | ;pos dw 0000h ;from 0,0 33 | ;vel dw 0101h ;v = (1,1) 34 | ;char db '*' 35 | ;color db 07H 36 | 37 | mov ax, [%1] 38 | mov [pos], ax 39 | mov ax, [%2] 40 | mov [vel], ax 41 | mov al, [%3] 42 | mov [char], al 43 | mov al, [%4] 44 | mov [color], al 45 | 46 | call PLAY 47 | 48 | mov ax, [pos] 49 | mov [%1], ax 50 | mov ax, [vel] 51 | mov [%2], ax 52 | %endmacro 53 | 54 | START: 55 | call DELAY 56 | ;call PLAY 57 | SINGLE pos1,vel1,char1,color1 58 | SINGLE pos2,vel2,char2,color2 59 | ;SINGLE pos3,vel3,char3,color3 60 | call SHOWNAME 61 | jmp START 62 | 63 | PLAY: 64 | call SETPOINTER 65 | call ELIMINATE 66 | 67 | call UPDATEPOS 68 | 69 | call SETPOINTER 70 | call SHOW 71 | ret 72 | 73 | SHOWNAME: 74 | mov cx,[msgLen] 75 | 76 | mov si,message 77 | 78 | mov di, (1*80 + 1) * 2 79 | 80 | mov dl,[msgColor] 81 | 82 | printChar: 83 | mov al,[si] 84 | inc si 85 | and dl,0Fh 86 | mov ah,dl 87 | add dl,1 88 | mov [es:di],ax 89 | add di,2 90 | loop printChar 91 | 92 | inc byte[msgColor] 93 | 94 | ret 95 | 96 | DELAY: 97 | mov cx, outDelay 98 | LOOP1: 99 | mov ax, inDelay 100 | LOOP2: 101 | dec ax 102 | jg LOOP2 103 | loop LOOP1 104 | 105 | ret 106 | 107 | UPDATEPOS: 108 | ;parameter: pos, vel 109 | mov ax,[pos] 110 | mov bx,[vel] 111 | 112 | ;update x 113 | add ah,bh 114 | cmp ah,MIN_X 115 | ja XNZ 116 | ;if x <= MIN_X 117 | mov bh,1 118 | XNZ: 119 | CMP ah,MAX_X-1 120 | jb XNF 121 | ;if x >= MAX_X-1 122 | mov bh,-1 123 | XNF: 124 | ;update y 125 | add al,bl 126 | cmp al,MIN_Y 127 | ja YNZ 128 | ;if y <= MIN_Y 129 | mov bl,1 130 | YNZ: 131 | CMP al,MAX_Y-1 132 | jb YNF 133 | ;if y >= MAX_Y-1 134 | mov bl,-1 135 | YNF: 136 | mov [pos],ax 137 | mov [vel],bx 138 | ret 139 | 140 | SETPOINTER: 141 | ;parameter pos, char 142 | mov ax, 0 143 | mov bx, [pos] ; bx = (x,y) 144 | mov al, bl 145 | mov cx, SCREEN_X 146 | mul cx ; ax *= SCREEN_X namely ax = y * SCREEN_X 147 | mov cx, 0 148 | mov cl, bh 149 | add ax, cx ; ax += x 150 | mov cx, 2 151 | mul cx 152 | mov bx, ax 153 | ret 154 | 155 | SHOW: 156 | ;new 157 | mov al, [char] 158 | mov ah, [color] 159 | mov [es:bx],ax 160 | ret 161 | 162 | ELIMINATE: 163 | ;clean 164 | mov ax, 0 165 | mov [es:bx],ax 166 | ret 167 | 168 | 169 | 170 | 171 | DATA: 172 | message db "WuKan's Program 1" 173 | msgLen dw $-message 174 | msgColor db 00h 175 | 176 | outCount dw outDelay 177 | inCount dw inDelay 178 | 179 | pos dw 0000h ;from 0,0 180 | vel dw 0101h ;v = (1,1) 181 | char db '*' 182 | color db 03H 183 | 184 | ;elements 185 | pos1 dw 0000h 186 | vel1 dw 0101h 187 | char1 db '*' 188 | color1 db 03H ;green 189 | 190 | pos2 dw 1003h 191 | vel2 dw 01FFh 192 | char2 db 'A' 193 | color2 db 0CFH ;twinkle red and light white 194 | 195 | pos3 dw 2019h 196 | vel3 dw 0FFFFh 197 | char3 db '@' 198 | color3 db 0EH ;yello 199 | 200 | times 510-($-$$) db 0 201 | dw 0xaa55 202 | -------------------------------------------------------------------------------- /lab6/tools/key.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | struct K{ 8 | string name; 9 | string smm[4]; 10 | string asc[4]; 11 | }; 12 | 13 | int main(){ 14 | ifstream fin("key.txt"); 15 | string name; 16 | string temp; 17 | 18 | vector ks; 19 | do{ 20 | K k; 21 | fin >> name; 22 | if(fin.eof())break; 23 | for (int i = 0;i < name.size();++i){ 24 | char c = name[i]; 25 | if (c >= 'a' && c <= 'z')c = c - 'a' +'A'; 26 | k.name += c; 27 | } 28 | for (int i = 0;i < 4;++i){ 29 | fin >> k.smm[i]; 30 | fin >> k.asc[i]; 31 | } 32 | ks.push_back(k); 33 | }while(!fin.eof()); 34 | ofstream fout("keyboard.h"); 35 | fout << "#ifndef _KEY_BOARD_H_" << endl; 36 | fout << "#define _KEY_BOARD_H_" << endl << endl; 37 | int o = 0; 38 | for (size_t i = 0;i < ks.size();++i){ 39 | K &k = ks[i]; 40 | string name = "KEY_" + k.name; 41 | fout << "#define " << name << " " << "0x" << k.smm[o] << k.asc[o] << endl; 42 | } 43 | o = 1; 44 | for (size_t i = 0;i < ks.size();++i){ 45 | K &k = ks[i]; 46 | string name = "KEY_SHIFT_" + k.name; 47 | fout << "#define " << name << " " << "0x" << k.smm[o] << k.asc[o] << endl; 48 | } 49 | o = 2; 50 | for (size_t i = 0;i < ks.size();++i){ 51 | K &k = ks[i]; 52 | string name = "KEY_CTRL_" + k.name; 53 | fout << "#define " << name << " " << "0x" << k.smm[o] << k.asc[o] << endl; 54 | } 55 | o = 3; 56 | for (size_t i = 0;i < ks.size();++i){ 57 | K &k = ks[i]; 58 | string name = "KEY_ALT_" + k.name; 59 | fout << "#define " << name << " " << "0x" << k.smm[o] << k.asc[o] << endl; 60 | } 61 | fout << endl << endl << "#endif" << endl; 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /lab6/tools/keybuild: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab6/tools/keybuild -------------------------------------------------------------------------------- /lab7/ReadMe.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab7/ReadMe.txt -------------------------------------------------------------------------------- /lab7/pic/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab7/pic/1.png -------------------------------------------------------------------------------- /lab7/pic/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab7/pic/2.png -------------------------------------------------------------------------------- /lab7/report/14348134吴侃lab7.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab7/report/14348134吴侃lab7.pdf -------------------------------------------------------------------------------- /lab8/Makefile: -------------------------------------------------------------------------------- 1 | BUILD_DIR = build 2 | DISK_DIR = disk 3 | KITS_DIR = kits 4 | SOURCE_DIR = source 5 | IMAGE_NAME= MiraiOS.img 6 | CC = g++ 7 | CFLAGS = -Iinclude -c -m16 -march=i386 -masm=intel -nostdlib -ffreestanding -mpreferred-stack-boundary=2 -lgcc -shared -std=c++11 -Wno-int-to-void-pointer-cast -fpermissive -fno-pie -fno-stack-protector 8 | 9 | AS = nasm 10 | ASFLAGS = 11 | LD = ld 12 | LDFLAGS = -m elf_i386 -N 13 | 14 | #如果不加-fda, 虽然能读Loader, 但无法读扇区:-( 15 | QEMU = qemu-system-x86_64 16 | QEMUFLAGS = -fda 17 | 18 | BOCHS = bochs 19 | BOCHSFLAGS = -q -f bochsrc.bxrc 20 | 21 | all: build_dir counter write_image write_knl build_progs 22 | 23 | 24 | build_dir: 25 | -mkdir $(BUILD_DIR) 26 | -mkdir $(DISK_DIR) 27 | 28 | counter: build_counter 29 | $(BUILD_DIR)/counter 30 | 31 | write_image: loadknl.bin 32 | dd if=/dev/zero of=$(IMAGE_NAME) count=2880 33 | dd if=$(BUILD_DIR)/loadknl.bin of=$(IMAGE_NAME) conv=notrunc 34 | 35 | write_knl: kernel.bin 36 | sudo mount -o loop $(IMAGE_NAME) disk/ 37 | sudo cp $(BUILD_DIR)/kernel.bin $(DISK_DIR)/ 38 | sudo umount $(DISK_DIR)/ 39 | 40 | build_progs: shell.com\ 41 | wkcn1.com wkcn2.com wkcn3.com wkcn4.com kan.com\ 42 | bs.com bpb.com ls.com help.com\ 43 | box.com\ 44 | testport.com testnew.com\ 45 | fork1.com fork2.com alpha.com\ 46 | mat.com letter.com fruit.com screen.com 47 | 48 | sudo mount -o loop $(IMAGE_NAME) disk/ 49 | 50 | for name in $^; do\ 51 | sudo cp $(BUILD_DIR)/$$name $(DISK_DIR)/;\ 52 | done 53 | 54 | sudo umount $(DISK_DIR)/ 55 | 56 | loadknl.bin: $(SOURCE_DIR)/loadknl.asm 57 | $(AS) $(ASFLAGS) -f bin $^ -o $(BUILD_DIR)/$@ 58 | 59 | kernel.bin: kernel.o os.o 60 | $(LD) $(LDFLAGS) -Ttext 0x7e00 --oformat binary $(BUILD_DIR)/kernel.o $(BUILD_DIR)/os.o -o $(BUILD_DIR)/$@ 61 | 62 | 63 | %.s: %.cpp 64 | $(CC) $(CFLAGS) -S $< -o $(BUILD_DIR)/$@ 65 | %.o: %.c 66 | $(CC) $(CFLAGS) $< -o $(BUILD_DIR)/$@ 67 | %.o: $(SOURCE_DIR)/%.cpp 68 | $(CC) $(CFLAGS) $< -o $(BUILD_DIR)/$@ 69 | %.o: $(SOURCE_DIR)/%.asm 70 | $(AS) $(ASFLAGS) -f elf32 $^ -o $(BUILD_DIR)/$@ 71 | %.com: %.o header.o 72 | #$(LD) $(LDFLAGS) -Ttext 0x100 --oformat binary $(BUILD_DIR)/header.o $(BUILD_DIR)/$< -o $(BUILD_DIR)/$@ 73 | $(LD) $(LDFLAGS) -T $(SOURCE_DIR)/linker_100.ld --oformat binary $(BUILD_DIR)/header.o $(BUILD_DIR)/$< -o $(BUILD_DIR)/$@ 74 | %.com: $(SOURCE_DIR)/%.asm 75 | $(AS) $(ASFLAGS) -f bin $^ -o $(BUILD_DIR)/$@ 76 | 77 | qemu: 78 | $(QEMU) $(QEMUFLAGS) $(IMAGE_NAME) 79 | 80 | run: qemu 81 | 82 | bochs: 83 | $(BOCHS) $(BOCHSFLAGS) 84 | 85 | build_counter: 86 | $(CC) $(SOURCE_DIR)/counter.cpp -o $(BUILD_DIR)/counter 87 | 88 | clean: 89 | -rm -rf $(BUILD_DIR) 90 | -rm -rf $(DISK_DIR) 91 | -------------------------------------------------------------------------------- /lab8/ReadMe.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab8/ReadMe.txt -------------------------------------------------------------------------------- /lab8/include/disk_op.h: -------------------------------------------------------------------------------- 1 | #ifndef _DISK_OP_H_ 2 | #define _DISK_OP_H_ 3 | 4 | #include "disk.h" 5 | 6 | char fat12name[11]; 7 | char targetname[11]; 8 | 9 | __attribute__((regparm(1))) 10 | bool rm(char *filename){ 11 | Entry e; 12 | ToFAT12Name(fat12name, filename); 13 | uint16_t eid = FindEntry(fat12name, &e); 14 | if(eid == 0xFFFF)return false; 15 | /* 16 | uint16_t cl = e.DIR_FstClus; 17 | uint16_t ne; 18 | while(cl < 0xFF8){ 19 | ne = GetNextFat(cl); 20 | SetClus(cl, 0); // 设置为空 21 | cl = ne; 22 | } 23 | */ 24 | e.DIR_Name[0] = 0xE5; // 标记为删除 25 | SetEntry(eid, &e); 26 | return true; 27 | } 28 | 29 | __attribute__((regparm(2))) 30 | bool mv(char *filename, char *target){ 31 | Entry e; 32 | bool diff = false; 33 | for(uint8_t i = 0;i < 11;++i){ 34 | if (filename[i] != target[i]){ 35 | diff = true; 36 | break; 37 | } 38 | } 39 | if (!diff)return false; // 没有更改名称 40 | ToFAT12Name(fat12name, filename); 41 | ToFAT12Name(targetname, target); 42 | uint16_t eid = FindEntry(fat12name, &e); 43 | if (eid == 0xFFFF)return false; 44 | memcpy(e.DIR_Name, targetname, 11); 45 | SetEntry(eid, &e); 46 | return true; 47 | } 48 | 49 | char cpbuf[512]; 50 | Entry te; 51 | __attribute__((regparm(2))) 52 | bool cp(char *filename, char *target){ 53 | Entry e; 54 | bool diff = false; 55 | for(uint8_t i = 0;i < 11;++i){ 56 | if (filename[i] != target[i]){ 57 | diff = true; 58 | break; 59 | } 60 | } 61 | if (!diff)return false; // 没有更改名称 62 | ToFAT12Name(fat12name, filename); 63 | ToFAT12Name(targetname, target); 64 | uint16_t eid = FindEntry(fat12name, &e); 65 | if (eid == 0xFFFF)return false; 66 | uint16_t cl = e.DIR_FstClus; 67 | uint16_t nid = FindEntry(targetname, &te); 68 | uint16_t ec = FindEmptyClus(); 69 | if (ec == 0xFFFF)return false; 70 | e.DIR_FstClus = ec; 71 | SetClus(ec, 0xFFF); 72 | memcpy(e.DIR_Name, targetname, 11); 73 | 74 | if (nid != 0xFFFF){ 75 | //删除旧数据 76 | //为了存储旧数据,暂时不实现 77 | }else{ 78 | nid = FindEmptyEntry(); 79 | if (nid == 0xFFFF)return false; 80 | } 81 | 82 | bool first = true; 83 | 84 | uint16_t wcl = ec; 85 | while(cl < 0xFF8){ 86 | if (!first)wcl = GetNextClus(wcl); 87 | if (wcl == 0xFFFF)return false; 88 | first = false; 89 | //拷贝扇区 90 | ReadFloppy(33 + (cl - 2), 1, cpbuf); 91 | WriteFloppy(33 + (wcl - 2), 1, cpbuf); 92 | cl = GetNextFat(cl); 93 | } 94 | 95 | SetEntryTime(&e); 96 | SetEntry(nid, &e); 97 | return true; 98 | } 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /lab8/include/fork.h: -------------------------------------------------------------------------------- 1 | #ifndef _TASK_H_ 2 | #define _TASK_H_ 3 | 4 | #include "pcb.h" 5 | #include "memory.h" 6 | 7 | uint8_t fork(){ 8 | INIT_SEGMENT(); 9 | ScheduleOFF; 10 | Schedule; 11 | uint16_t runid = GetRunID(); 12 | LoadPCB(runid); // note:IP! 13 | if (_p.KIND == K_FORK){ 14 | SetTaskAttr(runid,&_p.KIND,uint8_t(K_PROG)); 15 | ScheduleON; 16 | return 0; // 子进程返回0 17 | } 18 | uint8_t newID = FindEmptyPCB(); 19 | uint16_t addrseg = allocate(_p.SSIZE); 20 | if (addrseg == 0xFFFF){ 21 | ScheduleON; 22 | return 0xFF; 23 | } 24 | //[ds:si] -> [es:di] 25 | asm volatile("push ds;push si;push es;push di;" 26 | "mov ds,ax;" 27 | "mov es,dx;" 28 | "xor si,si;" 29 | "xor di,di;" 30 | "cld;" 31 | "COPY_PROG:;" 32 | "movsw;movsw;movsw;movsw;" 33 | "movsw;movsw;movsw;movsw;" 34 | "loop COPY_PROG;" 35 | "pop di;pop es;pop si;pop ds;" 36 | : 37 | :"a"(_p.SEG),"d"(addrseg),"c"(_p.SSIZE) 38 | ); 39 | 40 | // 注意, ID与RunID类型是不同的,db和dw 41 | _p.ID = newID; 42 | _p.CS = addrseg; 43 | _p.DS = addrseg; 44 | _p.SS = addrseg; 45 | _p.SEG = addrseg; 46 | _p.PARENT_ID = runid; 47 | _p.KIND = K_FORK; 48 | 49 | WritePCB(newID); 50 | INC_RunNum; 51 | ScheduleON; 52 | return newID; 53 | } 54 | 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /lab8/include/fstream.h: -------------------------------------------------------------------------------- 1 | #ifndef _FSTREAM_H_ 2 | #define _FSTREAM_H_ 3 | 4 | #endif 5 | -------------------------------------------------------------------------------- /lab8/include/interrupt.h: -------------------------------------------------------------------------------- 1 | #ifndef _INTERRUPT_H_ 2 | #define _INTERRUPT_H_ 3 | #include "defines.h" 4 | #include "io.h" 5 | //#include 6 | 7 | //一般C++函数, 会首先将ebp入栈, 最终恢复 8 | //G++编译出来的压栈都是4字节的(32 bits), 但是我们的nasm是16位的:-( 9 | //16位G++的内嵌汇编的iret操作的是EFLAGS,ECS,EIP; 因此, 我们要将可爱的flags,cs,ip转为32位~ 10 | //G++里内嵌汇编的iret为66cf, 内嵌的中断调用为16位int 11 | //nasm的16位iret为cf 12 | //不带局部变量的函数 13 | // 14 | #define CPP_INT_END asm volatile("pop ds;pop ebp;.BYTE 0xcf") 15 | //带局部变量的函数(ebp保存原来的esp) 16 | //leave恢复esp(用ebp做备份), 计数 +8 -6 17 | //push ebp; mov ebp, esp; esp被修改, ebp没有被改 18 | //注意, 这时的中断用的栈是用户栈 19 | #define CPP_INT_LEAVE asm volatile("pop ds;leave;.BYTE 0xcf") 20 | #define CPP_INT_HEADER asm volatile("push ds;push ax;mov ax, cs; mov ds, ax;pop ax;") 21 | __attribute__((regparm(3))) 22 | void WriteIVT(uint16_t id,uint16_t offset,uint16_t cs){ 23 | asm volatile( 24 | "push si;push es;" 25 | "mov es, ax;" 26 | "mov si, bx;" 27 | "mov es:[si], cx;" 28 | "mov es:[si+2], dx;" 29 | "pop es;pop si;" 30 | : 31 | :"a"(0),"b"(id * 4),"c"(offset),"d"(cs) 32 | ); 33 | } 34 | 35 | __attribute__((regparm(2))) 36 | void WriteIVT(uint16_t id, void (*func)()){ 37 | uint16_t cs; 38 | asm volatile("mov ax, cs;":"=a"(cs)); 39 | WriteIVT(id,(long)func,cs); 40 | } 41 | 42 | __attribute__((regparm(1))) 43 | void ExecuteINT(uint16_t id){ 44 | uint16_t ip, cs; 45 | asm volatile( 46 | "push es;" 47 | "mov es, ax;" 48 | "mov ax, es:[bx];" 49 | "mov bx, es:[bx + 2];" 50 | "pop es;" 51 | :"=a"(ip),"=b"(cs) 52 | :"a"(0),"b"(id * 4) 53 | ); 54 | uint16_t ocs; 55 | asm volatile("mov ax, cs;":"=a"(ocs)); 56 | //不知道为什么, 一定要加下面这一句, 否则崩溃:-( 57 | PrintStr("Execute interrupt 0x"); 58 | PrintHex(id);PrintStr(NEWLINE); 59 | char addr[4]; 60 | *((uint16_t*)(addr)) = ip; 61 | *((uint16_t*)(addr+2)) = cs; 62 | asm volatile( 63 | "push es;" 64 | "mov es, ax;" 65 | "pushf;" 66 | "call far ptr es:[bx];" 67 | "pop es;" 68 | : 69 | :"a"(ocs),"b"(addr) 70 | ); 71 | } 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /lab8/include/mem_base.h: -------------------------------------------------------------------------------- 1 | #ifndef _MEM_BASE_H_ 2 | #define _MEM_BASE_H_ 3 | 4 | #include 5 | 6 | struct MemBlock{ 7 | bool used; 8 | uint16_t left, right; //[left,right) 9 | uint16_t next; 10 | }; 11 | 12 | struct MemRecord{ 13 | MemBlock *data; 14 | uint16_t MaxBlockNum; 15 | }; 16 | 17 | __attribute__((regparm(3))) 18 | void mem_init(MemRecord &mem, uint16_t left, uint16_t right){ 19 | for (uint16_t i = 0;i < mem.MaxBlockNum + 1;++i)mem.data[i].used = false; 20 | 21 | mem.data[0].used = true; 22 | mem.data[0].next = 1; 23 | mem.data[0].left = left; 24 | mem.data[0].right = left; 25 | 26 | mem.data[1].used = true; 27 | mem.data[1].left = left; 28 | mem.data[1].right = right; 29 | mem.data[1].next = mem.MaxBlockNum; 30 | 31 | mem.data[mem.MaxBlockNum].used = true; 32 | mem.data[mem.MaxBlockNum].left = right; 33 | mem.data[mem.MaxBlockNum].right = right; 34 | }; 35 | 36 | __attribute__((regparm(2))) 37 | uint16_t mem_allocate(MemRecord &mem, uint16_t needSize){ 38 | //使用最佳适应算法, 每次找最小的分区 39 | bool first = true; 40 | uint16_t blockSize = 0; 41 | uint16_t lastp = 0; 42 | uint16_t goodlastp = 0; 43 | uint16_t goodp = 0; 44 | for (uint16_t p = mem.data[0].next;p != mem.MaxBlockNum;lastp = p, p = mem.data[p].next){ 45 | uint16_t u = mem.data[p].right - mem.data[p].left; 46 | if (u < needSize)continue; 47 | if (first || u < blockSize){ 48 | first = false; 49 | goodp = p; 50 | goodlastp = lastp; 51 | blockSize = u; 52 | } 53 | } 54 | if (first)return 0xFFFF; // 无法分配 55 | uint16_t addr = mem.data[goodp].left; 56 | //从链表中删除空间 57 | if (blockSize == needSize){ 58 | //刚好删除 59 | mem.data[goodp].used = false; 60 | mem.data[goodlastp].next = mem.data[goodp].next; 61 | }else{ 62 | //大于所要申请的空间 63 | //取前面部分 64 | mem.data[goodp].left += needSize; 65 | } 66 | return addr; 67 | } 68 | 69 | __attribute__((regparm(3))) 70 | void mem_free(MemRecord &mem, uint16_t addr, uint16_t freeSize){ 71 | //释放空间 72 | uint16_t lastp = 0; 73 | uint16_t p; 74 | for (p = mem.data[lastp].next;p != mem.MaxBlockNum;lastp = p, p = mem.data[p].next){ 75 | //找到>=上个节点的right值的点 76 | if (addr >= mem.data[lastp].right && addr < mem.data[p].left)break; 77 | } 78 | //这时, addr >= memdata[lastp].right 79 | if (addr == mem.data[lastp].right && lastp != 0){ 80 | //与上一个节点融合 81 | //lastp 一定不为0 82 | if (addr + freeSize >= mem.data[p].left){ 83 | //与p节点融合 84 | if (p != mem.MaxBlockNum){ 85 | mem.data[lastp].next = mem.data[p].next; 86 | mem.data[p].used = false; 87 | mem.data[lastp].right = mem.data[p].right; 88 | }else{ 89 | mem.data[lastp].right = addr + freeSize; 90 | } 91 | }else{ 92 | mem.data[lastp].right = addr + freeSize; 93 | } 94 | }else{ 95 | //与上一个节点不融合 96 | //lastp 可能为0 97 | if (addr + freeSize >= mem.data[p].left && p != mem.MaxBlockNum){ 98 | //与p节点融合 99 | mem.data[p].left = addr; 100 | }else{ 101 | //与前后都不融合 102 | uint16_t e; 103 | for (e = 1;e < mem.MaxBlockNum;++e){ 104 | if (!mem.data[e].used)break; 105 | } 106 | mem.data[lastp].next = e; 107 | mem.data[e].used = true; 108 | mem.data[e].next = p; 109 | mem.data[e].left = addr; 110 | mem.data[e].right = addr + freeSize; 111 | } 112 | } 113 | } 114 | 115 | 116 | #endif 117 | -------------------------------------------------------------------------------- /lab8/include/memory.h: -------------------------------------------------------------------------------- 1 | #ifndef _MEMORY_H_ 2 | #define _MEMORY_H_ 3 | 4 | #include 5 | #include "mem_base.h" 6 | #include "pcb.h" 7 | 8 | struct MemAllocRecord{ 9 | bool used; 10 | uint16_t p; 11 | uint16_t size; 12 | }; 13 | 14 | #define mem_null ((void*)0xFFFF) 15 | const uint16_t MaxBlockNum = 32; 16 | const uint16_t MaxAllocNum = 256; 17 | const uint16_t SPACE_SIZE = 0x4000; // 16k, 这里用字节表示 18 | //Prog Memory 19 | MemAllocRecord mar[MaxAllocNum]; 20 | MemBlock memdata[MaxBlockNum + 1]; 21 | MemRecord memRecord; 22 | 23 | __attribute__((regparm(1))) 24 | uint16_t allocate(uint16_t needSize){ 25 | asm volatile("int 0x21;"::"a"(0x0700)); // 关闭进程切换, 更新PCB值 26 | uint16_t addr; 27 | asm volatile( 28 | "int 0x23;" 29 | :"=a"(addr) 30 | :"a"(0x0100),"c"(needSize) 31 | ); 32 | 33 | asm volatile("int 0x21;"::"a"(0x0800)); // 开启进程切换 34 | return addr; 35 | } 36 | 37 | __attribute__((regparm(2))) 38 | void free(uint16_t addr, uint16_t freeSize){ 39 | asm volatile("int 0x21;"::"a"(0x0700)); // 关闭进程切换, 更新PCB值 40 | asm volatile( 41 | "int 0x23;" 42 | : 43 | :"a"(0x0000),"b"(addr),"c"(freeSize) 44 | ); 45 | asm volatile("int 0x21;"::"a"(0x0800)); // 开启进程切换 46 | } 47 | 48 | 49 | //需要手动开启 50 | void mem_init(){ 51 | INIT_SEGMENT(); 52 | memRecord.data = memdata; 53 | memRecord.MaxBlockNum = MaxBlockNum; 54 | uint16_t runid; 55 | asm volatile("int 0x21;":"=a"(runid):"a"(0x0200)); 56 | uint16_t si, SSIZE; 57 | GetTaskAttr(runid, &_p.SIZE, si); 58 | GetTaskAttr(runid, &_p.SSIZE, SSIZE); 59 | uint16_t code = ((si + 0x100 + (1<<4) - 1) >> 4) << 4; 60 | mem_init(memRecord,code,SSIZE<<4); 61 | for (int i = 0;i < MaxAllocNum;++i)mar[i].used = false; 62 | } 63 | 64 | void * operator new(size_t size){ 65 | uint16_t p = mem_allocate(memRecord,size); 66 | if (p != 0xFFFF){ 67 | int i; 68 | for (i = 0;i < MaxAllocNum;++i){ 69 | if (!mar[i].used)break; 70 | } 71 | mar[i].used = true; 72 | mar[i].p = p; 73 | mar[i].size = size; 74 | } 75 | return (void*)(unsigned int)p; 76 | } 77 | 78 | void * operator new[](size_t size){ 79 | uint16_t p = mem_allocate(memRecord,size); 80 | if (p != 0xFFFF){ 81 | int i; 82 | for (i = 0;i < MaxAllocNum;++i){ 83 | if (!mar[i].used)break; 84 | } 85 | mar[i].used = true; 86 | mar[i].p = p; 87 | mar[i].size = size; 88 | } 89 | return (void*)(unsigned int)p; 90 | } 91 | 92 | void operator delete(void *p){ 93 | for (int i = 0;i < MaxAllocNum;++i){ 94 | if (mar[i].used && mar[i].p == (uint16_t)(unsigned long)p){ 95 | mar[i].used = false; 96 | mem_free(memRecord, mar[i].p, mar[i].size); 97 | return; 98 | } 99 | } 100 | } 101 | 102 | void operator delete[](void *p){ 103 | for (int i = 0;i < MaxAllocNum;++i){ 104 | if (mar[i].used && mar[i].p == (uint16_t)(unsigned long)p){ 105 | mar[i].used = false; 106 | mem_free(memRecord, mar[i].p, mar[i].size); 107 | return; 108 | } 109 | } 110 | } 111 | 112 | #endif 113 | -------------------------------------------------------------------------------- /lab8/include/msg.h: -------------------------------------------------------------------------------- 1 | #ifndef _MSG_H_ 2 | #define _MSG_H_ 3 | 4 | #include "msg_base.h" 5 | 6 | __attribute__((regparm(2))) 7 | bool Send(uint8_t target, MsgPack *p){ 8 | uint16_t retn; 9 | asm volatile( 10 | "mov bx, cs;" 11 | "int 0x25;" 12 | :"=a"(retn) 13 | :"a"(0x3000 | target), "c"((unsigned long)p) 14 | :"bx" 15 | ); 16 | return retn; 17 | } 18 | 19 | __attribute__((regparm(1))) 20 | bool IRecvAll(MsgPack *p){ 21 | uint16_t retn; 22 | asm volatile( 23 | "mov bx, cs;" 24 | "int 0x25;" 25 | :"=a"(retn) 26 | :"a"(0x4300), "c"((unsigned long)p) 27 | :"bx" 28 | ); 29 | return retn; 30 | } 31 | #endif 32 | -------------------------------------------------------------------------------- /lab8/include/msg_base.h: -------------------------------------------------------------------------------- 1 | #ifndef _MSG_BASE_H_ 2 | #define _MSG_BASE_H_ 3 | 4 | #include "defines.h" 5 | 6 | struct MsgPack{ 7 | uint16_t func; 8 | Addr data; // 指向数据 9 | uint16_t size; 10 | }; 11 | 12 | struct Message{ 13 | bool used; 14 | bool visited; 15 | uint16_t id; 16 | uint8_t source, target; 17 | uint16_t next; 18 | Addr pack; // 指向MsgPack 19 | }; 20 | #endif 21 | -------------------------------------------------------------------------------- /lab8/include/os_msg.h: -------------------------------------------------------------------------------- 1 | #ifndef _OS_MSG_H_ 2 | #define _OS_MSG_H_ 3 | 4 | #include "msg_base.h" 5 | #include "pcb.h" 6 | #include "sem.h" 7 | 8 | const uint16_t MsgNum = 128; 9 | Message messages[MsgNum]; 10 | uint16_t MsgSem; 11 | 12 | void INIT_MSG(){ 13 | for (uint16_t i = 0;i < MsgNum;++i){ 14 | messages[i].used = 0; 15 | messages[i].id = i; 16 | } 17 | MsgSem = semCreate(1); 18 | } 19 | 20 | 21 | //阻塞发送 22 | //输入msgpack 23 | __attribute__((regparm(3))) 24 | bool Send(uint8_t target, uint16_t cs, uint16_t ip){ 25 | //semWait(MsgSem); 26 | PrintStr("Send"); 27 | uint16_t i; 28 | for (i = 0;i < MsgNum;++i){ 29 | if (!messages[i].used)break; 30 | } 31 | if (i == MsgNum)return false; 32 | 33 | messages[i].used = true; 34 | messages[i].visited = false; 35 | messages[i].source = GetRunID(); 36 | messages[i].target = target; 37 | memcpy(GetAddr(&messages[i].pack),MakeAddr(cs,ip),sizeof(MsgPack)); 38 | 39 | //semSignal(MsgSem); 40 | 41 | //阻塞自己 42 | PrintStr("BB"); 43 | SetTaskAttr(GetRunID(), &_p.STATE, (uint8_t)T_BLOCKED); 44 | Schedule; 45 | 46 | return true; 47 | } 48 | 49 | __attribute__((regparm(2))) 50 | bool Send(uint8_t target, MsgPack *p){ 51 | uint16_t cs; 52 | asm volatile("mov ax, cs;":"=a"(cs)); 53 | return Send(target, cs, (unsigned long)p); 54 | } 55 | 56 | //非阻塞接收 57 | //目前不考虑信息发送的顺序! 58 | //返回msgpack 59 | __attribute__((regparm(2))) 60 | bool IRecvAll(uint16_t cs, uint16_t ip){ 61 | //semWait(MsgSem); 62 | uint16_t runid = GetRunID(); 63 | bool finded = false; 64 | for (uint16_t i = 0;i < MsgNum;++i){ 65 | if (messages[i].used && messages[i].target == runid){ 66 | finded = true; 67 | memcpy(MakeAddr(cs,ip), GetAddr(&messages[i].pack), sizeof(MsgPack)); 68 | //恢复运行态 69 | SetTaskAttr(messages[i].source, &_p.STATE, (uint8_t)T_RUNNING); 70 | messages[i].used = false; 71 | //暂时不考虑visited处理 72 | break; 73 | } 74 | } 75 | //semSignal(MsgSem); 76 | return finded; 77 | } 78 | 79 | __attribute__((regparm(1))) 80 | bool IRecvAll(MsgPack *p){ 81 | uint16_t cs; 82 | asm volatile("mov ax, cs;":"=a"(cs)); 83 | return IRecvAll(cs, (unsigned long)p); 84 | } 85 | #endif 86 | -------------------------------------------------------------------------------- /lab8/include/os_sem.h: -------------------------------------------------------------------------------- 1 | #ifndef _OS_SEM_H_ 2 | #define _OS_SEM_H_ 3 | 4 | #include "pcb.h" 5 | 6 | // 汇编的cmpxchg可以原子语句 7 | // 这里我使用屏蔽进程切换的方式 8 | // Block链由PCB项记录BLOCK_NEXT 9 | 10 | struct sem{ 11 | uint8_t used; 12 | uint8_t flag; // bool 也会变为1字节 13 | int8_t count; 14 | uint8_t next; 15 | uint8_t runid; // 释放信号用 16 | }; 17 | 18 | const uint8_t MaxSemNum = 128; 19 | sem sems[MaxSemNum]; 20 | 21 | uint8_t semtemp; 22 | __attribute__((regparm(1))) 23 | void os_semWait(uint8_t sid){ 24 | //INIT_SEGMENT(); 25 | uint16_t ax = 1; 26 | while(1){ 27 | //原子交换 28 | asm volatile("lock xchg cs:[bx],al;":"=a"(ax):"b"(&sems[sid].flag),"a"(ax)); 29 | if ((ax&0x00FF) == 1)continue; 30 | break; 31 | } 32 | --sems[sid].count; 33 | //PrintNum(sems[sid].count,YELLOW); 34 | uint16_t runid = GetRunID(); 35 | if (sems[sid].count < 0){ 36 | //PrintStr("BLOCK"); 37 | //加入链表尾部 38 | if (sems[sid].next == 0){ 39 | //信号量阻塞队列为空 40 | sems[sid].next = (uint8_t)runid; 41 | }else{ 42 | uint8_t nex = sems[sid].next; 43 | while(1){ 44 | GetTaskAttr(nex,&_p.BLOCK_NEXT,semtemp); 45 | if (semtemp == 0)break; 46 | nex = semtemp; 47 | } 48 | SetTaskAttr(nex,&_p.BLOCK_NEXT,(uint8_t)runid); 49 | } 50 | //阻塞该进程 51 | SetTaskAttr(runid, &_p.STATE, (uint8_t)T_BLOCKED); 52 | } 53 | sems[sid].flag = 0; 54 | //防止无法及时调度, 暂时没有其他方法解决, 可能是调度程序的问题 55 | /* 56 | while(1){ 57 | if (GetTaskState(runid) != T_BLOCKED)break; 58 | }*/ 59 | Schedule; 60 | } 61 | 62 | __attribute__((regparm(1))) 63 | void os_semSignal(uint8_t sid){ 64 | //INIT_SEGMENT(); 65 | uint16_t ax = 1; 66 | while(1){ 67 | //原子交换 68 | asm volatile("lock xchg cs:[bx],al;":"=a"(ax):"b"(&sems[sid].flag),"a"(ax)); 69 | if ((ax&0x00FF) == 1)continue; 70 | break; 71 | } 72 | ++sems[sid].count; 73 | //PrintNum(sems[sid].count,LRED); 74 | if (sems[sid].count <= 0){ 75 | //将sems[sid].next移出 76 | uint8_t zid = sems[sid].next; 77 | GetTaskAttr(zid,&_p.BLOCK_NEXT,semtemp); 78 | SetTaskAttr(zid,&_p.BLOCK_NEXT,uint8_t(0)); 79 | sems[sid].next = semtemp; 80 | //已经移出来了 81 | SetTaskAttr(zid, &_p.STATE, (uint8_t)T_RUNNING); 82 | } 83 | sems[sid].flag = 0; 84 | } 85 | 86 | __attribute__((regparm(1))) 87 | uint8_t os_semCreate(int8_t count){ 88 | for (uint8_t i = 0;i < MaxSemNum;++i){ 89 | if (!sems[i].used){ 90 | sems[i].used = 1; 91 | sems[i].count = count; 92 | sems[i].next = 0; 93 | sems[i].flag = 0; 94 | sems[i].runid = GetRunID(); 95 | return i; 96 | } 97 | } 98 | return 0xFF; 99 | } 100 | 101 | __attribute__((regparm(1))) 102 | void os_semDel(uint8_t sid){ 103 | sems[sid].used = false; 104 | } 105 | 106 | 107 | __attribute__((regparm(1))) 108 | void os_semRelease(uint8_t runid){ 109 | for (uint8_t i = 0;i < MaxSemNum;++i){ 110 | if (sems[i].used && sems[i].runid == runid){ 111 | sems[i].used = false; 112 | } 113 | } 114 | } 115 | 116 | void INIT_SEM(){ 117 | for (int i = 0;i < MaxSemNum;++i){ 118 | sems[i].used = 0; 119 | } 120 | } 121 | 122 | #endif 123 | -------------------------------------------------------------------------------- /lab8/include/port.h: -------------------------------------------------------------------------------- 1 | #ifndef _PORT_H_ 2 | #define _PORT_H_ 3 | /* 4 | ;22H进程, 进程通信 5 | 6 | ;ah = 00h 读 7 | ;ah = 01h 写 8 | ;ah = 02h 信号量设置(bh=0, 清零; bh=1, 加1; bh=2, 减1; bh=3, 设置为bl值) 9 | ;ah = 03h 设置端口 10 | ;ah = 04h 关闭端口 11 | ;ah = 05h 只返回信号量 12 | ;al = 端口值 13 | ;基地址bx, 缓存大小cx, 段地址dx 14 | ;返回信号量(ax) 15 | */ 16 | #include "defines.h" 17 | #include "sem.h" 18 | #include "portsList.h" 19 | 20 | __attribute__((regparm(3))) 21 | void SetPort(uint8_t portID, void* varAddr, uint16_t size){ 22 | uint16_t cs; 23 | asm volatile("mov ax,cs;":"=a"(cs)); 24 | asm volatile("int 0x22;" 25 | : 26 | :"a"((3 << 8) | portID), "b"(varAddr), "c"(size), "d"(cs) 27 | ); 28 | } 29 | 30 | __attribute__((regparm(3))) 31 | uint8_t ReadPort(uint8_t portID, void* varAddr, uint16_t size){ 32 | uint16_t cs; 33 | uint8_t v; 34 | asm volatile("mov ax,cs;":"=a"(cs)); 35 | asm volatile("int 0x22;" 36 | :"=a"(v) 37 | :"a"((0 << 8) | portID), "b"(varAddr), "c"(size), "d"(cs) 38 | ); 39 | return v; 40 | } 41 | 42 | __attribute__((regparm(3))) 43 | void WritePort(uint8_t portID, void* varAddr, uint16_t size){ 44 | uint16_t cs; 45 | asm volatile("mov ax,cs;":"=a"(cs)); 46 | asm volatile("int 0x22;" 47 | : 48 | :"a"((1 << 8) | portID), "b"(varAddr), "c"(size), "d"(cs) 49 | ); 50 | } 51 | 52 | 53 | __attribute__((regparm(2))) 54 | void SetPortMsgV(uint8_t portID, uint8_t v){ 55 | uint16_t cs; 56 | asm volatile("mov ax,cs;":"=a"(cs)); 57 | asm volatile("int 0x22;" 58 | : 59 | :"a"((2<<8) | portID), "b"((3<<8) | v) 60 | ); 61 | } 62 | 63 | 64 | __attribute__((regparm(1))) 65 | uint8_t GetPortMsgV(uint8_t portID){ 66 | uint8_t v; 67 | asm volatile("int 0x22;" 68 | :"=a"(v) 69 | :"a"((5<<8) | portID) 70 | ); 71 | return v; 72 | } 73 | 74 | /*端口信号量支持*/ 75 | 76 | __attribute__((regparm(2))) 77 | void PortSemCreate(uint8_t portID, int8_t count){ 78 | SetPortMsgV(portID, semCreate(count)); 79 | } 80 | 81 | __attribute__((regparm(1))) 82 | void PortSemDel(uint8_t portID){ 83 | uint8_t sid = GetPortMsgV(portID); 84 | semDel(sid); 85 | } 86 | 87 | 88 | __attribute__((regparm(1))) 89 | void PortSemWait(uint8_t portID){ 90 | uint8_t sid = GetPortMsgV(portID); 91 | semWait(sid); 92 | } 93 | 94 | __attribute__((regparm(1))) 95 | void PortSemSignal(uint8_t portID){ 96 | uint8_t sid = GetPortMsgV(portID); 97 | semSignal(sid); 98 | } 99 | #endif 100 | -------------------------------------------------------------------------------- /lab8/include/portsList.h: -------------------------------------------------------------------------------- 1 | #ifndef _PORTSLIST 2 | #define _PORTSLIST 3 | 4 | enum PORTS_LIST{ 5 | READYPROG_PORT = 3, 6 | RUNPROGRETN_PORT = 4, 7 | TALK_PORT = 5, 8 | SHELLMODE_PORT = 6 9 | }; 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /lab8/include/prog.h: -------------------------------------------------------------------------------- 1 | #ifndef _PROG_H_ 2 | #define _PROG_H_ 3 | 4 | #include 5 | 6 | struct ReadyProg{ 7 | uint8_t uid; 8 | char filename[12]; 9 | uint16_t allocatedSize; 10 | }; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /lab8/include/screen.h: -------------------------------------------------------------------------------- 1 | #ifndef _SCREEN_H_ 2 | #define _SCREEN_H_ 3 | 4 | #include 5 | 6 | const uint16_t SCREEN_S = (80 * 25 * 2 / 16); 7 | 8 | __attribute__((regparm(1))) 9 | void SaveScreen(uint16_t id){ 10 | uint16_t SCREEN_SEGMENT; 11 | asm volatile("sti;int 0x21;":"=a"(SCREEN_SEGMENT):"a"(0x0B00)); 12 | asm volatile("push ds;push es;mov es, ax;mov ds, dx"::"a"(0xB800),"d"(SCREEN_SEGMENT + SCREEN_S * (id - 1))); 13 | for (int i = 0;i < 80 * 25 * 2;++i){ 14 | asm volatile("mov al, es:[bx];mov ds:[bx],al;"::"b"(i):"ax"); 15 | } 16 | asm volatile("pop es;pop ds;"); 17 | } 18 | 19 | __attribute__((regparm(1))) 20 | void LoadScreen(uint16_t id){ 21 | uint16_t SCREEN_SEGMENT; 22 | asm volatile("sti;int 0x21;":"=a"(SCREEN_SEGMENT):"a"(0x0B00)); 23 | asm volatile("push ds;push es;mov es, ax;mov ds, dx"::"a"(0xB800),"d"(SCREEN_SEGMENT + SCREEN_S * (id - 1))); 24 | for (int i = 0;i < 80 * 25 * 2;++i){ 25 | asm volatile("mov al, ds:[bx];mov es:[bx],al;"::"b"(i):"ax"); 26 | } 27 | asm volatile("pop es;pop ds;"); 28 | } 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /lab8/include/sem.h: -------------------------------------------------------------------------------- 1 | #ifndef _SEM_H_ 2 | #define _SEM_H_ 3 | #include 4 | 5 | __attribute__((regparm(1))) 6 | void semWait(uint8_t sid){ 7 | uint16_t ax = 0x0100 | sid; 8 | /* 9 | asm volatile( 10 | "pushf;" 11 | "call far ptr cs:[bx];" 12 | : 13 | :"a"(ax),"b"(0x25 * 4) 14 | ); 15 | */ 16 | asm volatile("int 0x25"::"a"(ax)); 17 | } 18 | 19 | __attribute__((regparm(1))) 20 | void semSignal(uint8_t sid){ 21 | uint16_t ax = 0x0200 | sid; 22 | /* 23 | asm volatile( 24 | "pushf;" 25 | "call far ptr cs:[bx];" 26 | : 27 | :"a"(ax),"b"(0x25 * 4) 28 | ); 29 | */ 30 | 31 | asm volatile("int 0x25"::"a"(ax)); 32 | } 33 | 34 | 35 | __attribute__((regparm(1))) 36 | uint8_t semCreate(int8_t count){ 37 | uint16_t ax = 0x0000 | (uint16_t)count; 38 | uint8_t sid; 39 | 40 | /* 41 | asm volatile( 42 | "pushf;" 43 | "call far ptr cs:[bx];" 44 | :"=a"(sid) 45 | :"a"(ax),"b"(0x25 * 4) 46 | ); 47 | */ 48 | 49 | asm volatile("int 0x25":"=a"(sid):"a"(ax)); 50 | return sid; 51 | } 52 | 53 | __attribute__((regparm(1))) 54 | void semDel(uint8_t sid){ 55 | uint16_t ax = 0x0400 | sid; 56 | asm volatile("int 0x25"::"a"(ax)); 57 | } 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /lab8/include/string.h: -------------------------------------------------------------------------------- 1 | #ifndef _STRING_H_ 2 | #define _STRING_H_ 3 | 4 | #include "defines.h" 5 | 6 | __attribute__((regparm(1))) 7 | int strlen(const char *s){ 8 | int i = 0; 9 | while(*(s++))i++; 10 | return i; 11 | } 12 | 13 | __attribute__((regparm(2))) 14 | int strcmp(const char *astr,const char *bstr){ 15 | // = 0 16 | // < -1 17 | // > 1 18 | while ((*astr) && (*bstr)){ 19 | if (*astr != *bstr){ 20 | if (*astr < *bstr)return -1; 21 | return 1; 22 | } 23 | ++astr; 24 | ++bstr; 25 | } 26 | return (*astr) - (*bstr); 27 | } 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /lab8/include/thread.h: -------------------------------------------------------------------------------- 1 | #ifndef _THREAD_H_ 2 | #define _THREAD_H_ 3 | 4 | #include "pcb.h" 5 | #include "memory.h" 6 | 7 | struct thread_t{ 8 | uint16_t tid; 9 | }; 10 | 11 | uint8_t parentID; // 使用引用要放外面? 12 | __attribute__((regparm(3))) 13 | uint8_t thread_create(thread_t *t, __attribute__((regparm(1)))void* (*func)(void*), void *attr){ 14 | ScheduleOFF; 15 | Schedule; 16 | INIT_SEGMENT(); 17 | uint16_t runid = GetRunID(); 18 | LoadPCB(runid); // note:IP! 19 | if (_p.KIND == K_THREAD){ 20 | void *result = func(attr); // 执行函数 21 | SetTaskState(runid, T_DEAD); 22 | GetTaskAttr(runid, &_p.PARENT_ID, parentID); 23 | SetTaskAttr(parentID, &_p.STATE, uint8_t(T_RUNNING)); // 让父亲返回RUNNING态 24 | ScheduleON; 25 | asm volatile("mov ax, bx;"::"b"((uint16_t)(unsigned long)result)); 26 | Schedule; 27 | while(1){} 28 | return 0; // 子进程返回0 29 | } 30 | uint8_t newID = FindEmptyPCB(); 31 | uint16_t addrseg = allocate(0x10); 32 | if (addrseg == 0xFFFF){ 33 | ScheduleON; 34 | return 0xFF; 35 | } 36 | //[ds:si] -> [es:di] 37 | asm volatile("push ds;push si;push es;push di;" 38 | "mov ds,ax;" 39 | "mov es,dx;" 40 | "xor si,si;" 41 | "xor di,di;" 42 | "cld;" 43 | "COPY_STACK:;" 44 | "movsw;movsw;movsw;movsw;" 45 | "movsw;movsw;movsw;movsw;" 46 | "loop COPY_STACK;" 47 | "pop di;pop es;pop si;pop ds;" 48 | : 49 | :"a"(_p.SEG),"d"(addrseg),"c"(0x10) 50 | ); 51 | 52 | // 注意, ID与RunID类型是不同的,db和dw 53 | _p.ID = newID; 54 | _p.SS = addrseg; 55 | _p.SEG = addrseg; 56 | _p.SSIZE = 0x10; 57 | _p.PARENT_ID = runid; 58 | _p.KIND = K_THREAD; 59 | t->tid = newID; 60 | WritePCB(newID); 61 | INC_RunNum; 62 | ScheduleON; 63 | return newID; 64 | } 65 | 66 | 67 | __attribute__((regparm(2))) 68 | uint8_t thread_join(thread_t _t, void **_thread_retn){ 69 | INIT_SEGMENT(); 70 | uint16_t tid = _t.tid; 71 | uint16_t runid = GetRunID(); 72 | while(1){ 73 | if (GetTaskState(tid) == T_DEAD)break; 74 | SetTaskAttr(runid, &_p.STATE, uint8_t(T_BLOCKED)); // 设置自己为阻塞态 75 | Schedule; 76 | } 77 | uint16_t ax; 78 | GetTaskAttr(tid, &_p.AX, ax); 79 | //SetTaskAttr(tid, &_p.KIND, (uint8_t)K_PROG); // 设为普通程序, 并杀死 80 | if (_thread_retn)*_thread_retn = (void*)(long)ax; 81 | return tid; 82 | } 83 | #endif 84 | -------------------------------------------------------------------------------- /lab8/include/version.h: -------------------------------------------------------------------------------- 1 | #define RELEASE_TIMES 1251 2 | -------------------------------------------------------------------------------- /lab8/pic/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab8/pic/1.png -------------------------------------------------------------------------------- /lab8/pic/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab8/pic/2.png -------------------------------------------------------------------------------- /lab8/pic/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab8/pic/3.png -------------------------------------------------------------------------------- /lab8/report/14348134吴侃lab8.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab8/report/14348134吴侃lab8.docx -------------------------------------------------------------------------------- /lab8/report/14348134吴侃lab8.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wkcn/OSLabs/9f88f02dbeee8930e3dadac8b51e54dcaad5175f/lab8/report/14348134吴侃lab8.pdf -------------------------------------------------------------------------------- /lab8/source/alpha.cpp: -------------------------------------------------------------------------------- 1 | #include "fork.h" 2 | #include "io.h" 3 | 4 | char str[64] = "WhAlE aNd MoBuLA"; 5 | int main(){ 6 | PrintStr(str,LBLUE); 7 | PrintStr(NEWLINE); 8 | if (fork()){ 9 | //大写 10 | asm volatile( 11 | "mov dx,cs;" 12 | "int 0x24;" 13 | : 14 | :"a"(0x0100),"b"(str) 15 | :"dx" 16 | ); 17 | PrintStr(str,RED); 18 | }else{ 19 | //小写 20 | asm volatile( 21 | "mov dx,cs;" 22 | "int 0x24;" 23 | : 24 | :"a"(0x0000),"b"(str) 25 | :"dx" 26 | ); 27 | PrintStr(str,LGREEN); 28 | } 29 | PrintStr(NEWLINE); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /lab8/source/bpb.cpp: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | 3 | #pragma pack (1) // 按1字节对齐 4 | struct FAT12Header{ 5 | dw jmpShort;//BS_jmpBOOT 一个短跳转指令 6 | db nop; 7 | db BS_OEMName[8]; // 厂商名 8 | dw BPB_BytesPerSec; //每扇区字节数(Bytes/Sector) 0x200 9 | db BPB_SecPerClus; //每簇扇区数(Sector/Cluster) 0x1 10 | dw BPB_ResvdSecCnt; //Boot记录占用多少扇区 ox1 11 | db BPB_NumFATs; //共有多少FAT表 0x2 12 | dw BPB_RootEntCnt; //根目录区文件最大数 0xE0 13 | dw BPB_TotSec16; //扇区总数 0xB40[2*80*18] 14 | db BPB_Media; //介质描述符 0xF0 15 | dw BPB_FATSz16; //每个FAT表所占扇区数 0x9 16 | dw BPB_SecPerTrk; //每磁道扇区数(Sector/track) 0x12 17 | dw BPB_NumHeads; //磁头数(面数) 0x2 18 | dd BPB_HiddSec; //隐藏扇区数 0 19 | dd BPB_TotSec32; //如果BPB_TotSec16=0,则由这里给出扇区数 0 20 | db BS_DrvNum; //INT 13H的驱动器号 0 21 | db BS_Reserved1; //保留,未使用 0 22 | db BS_BootSig; //扩展引导标记(29h) 0x29 23 | dd BS_VolID; //卷序列号 0 24 | db BS_VolLab[11]; //卷标 'wkcn' 25 | db BS_FileSysType[8]; //文件系统类型 'FAT12' 26 | db other[448]; //引导代码及其他数据 引导代码(剩余空间用0填充) 27 | dw _55aa; //第510字节为0x55,第511字节为0xAA 0xAA55 28 | }; 29 | 30 | 31 | __attribute__((regparm(3))) 32 | void ReadFloppy(uint16_t sectorID, uint8_t sectorNum, char *data){ 33 | const uint16_t SecPerTrk = 18; 34 | //const uint16_t BytsPerSec = 512; 35 | uint8_t y = sectorID / SecPerTrk; 36 | uint8_t z = sectorID % SecPerTrk; 37 | uint8_t cl = z + 1; // 起始扇区号 38 | uint8_t ch = y >> 1; // 柱面号 39 | uint8_t dh = y & 1; // 磁头号 40 | uint8_t dl = 0; // 驱动器号, 0表示软盘A 41 | uint8_t ah = 2; // 功能号 42 | uint8_t al = sectorNum; // 读扇区数 43 | asm volatile( 44 | "push es;" 45 | "push ax;" 46 | "mov ax, ds;" 47 | "mov es, ax;" 48 | "pop ax;" 49 | "int 0x13;" 50 | "pop es;" 51 | : 52 | :"a"((ah<<8)|al),"b"(data),"c"((ch<<8)|cl),"d"((dh<<8)|dl) 53 | ); 54 | } 55 | 56 | 57 | FAT12Header header; 58 | int main(){ 59 | ReadFloppy(0,1,(char*)&header); 60 | 61 | PrintStr("jmpShort dw 0x"); 62 | PrintHex((header.jmpShort >> 8) & 0xFF); 63 | PrintHex((header.jmpShort) & 0xFF); 64 | PrintStr(NEWLINE); 65 | PrintStr("nop"); 66 | PrintStr(NEWLINE); 67 | PrintStr("OEMName db \""); 68 | PrintStrN(header.BS_OEMName,8); 69 | PrintChar('\"'); 70 | PrintStr(NEWLINE); 71 | 72 | PrintStr("BytesPerSec dw "); 73 | PrintNum(header.BPB_BytesPerSec); 74 | PrintStr(NEWLINE); 75 | 76 | PrintStr("SecPerClus db "); 77 | PrintNum(header.BPB_SecPerClus); 78 | PrintStr(NEWLINE); 79 | 80 | PrintStr("ResvdSecCnt dw "); 81 | PrintNum(header.BPB_ResvdSecCnt); 82 | PrintStr(NEWLINE); 83 | 84 | PrintStr("NumFATs db "); 85 | PrintNum(header.BPB_NumFATs); 86 | PrintStr(NEWLINE); 87 | 88 | PrintStr("RootEntCnt dw "); 89 | PrintNum(header.BPB_RootEntCnt); 90 | PrintStr(NEWLINE); 91 | 92 | PrintStr("TotSec16 dw "); 93 | PrintNum(header.BPB_TotSec16); 94 | PrintStr(NEWLINE); 95 | 96 | PrintStr("Media db 0x"); 97 | PrintHex(header.BPB_Media); 98 | PrintStr(NEWLINE); 99 | 100 | PrintStr("FatSz16 dw "); 101 | PrintNum(header.BPB_FATSz16); 102 | PrintStr(NEWLINE); 103 | 104 | PrintStr("SecPerTrk dw "); 105 | PrintNum(header.BPB_SecPerTrk); 106 | PrintStr(NEWLINE); 107 | 108 | PrintStr("NumHeads dw "); 109 | PrintNum(header.BPB_NumHeads); 110 | PrintStr(NEWLINE); 111 | 112 | PrintStr("HiddSec dd 0x"); 113 | PrintNum(header.BPB_HiddSec); 114 | PrintStr(NEWLINE); 115 | 116 | PrintStr("TotSec32 dd 0x"); 117 | PrintNum(header.BPB_TotSec32); 118 | PrintStr(NEWLINE); 119 | 120 | return 0; 121 | } 122 | -------------------------------------------------------------------------------- /lab8/source/bs.cpp: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | #include "disk.h" 3 | 4 | FAT12Header header; 5 | int main(){ 6 | 7 | ReadFloppy(0,1,&header); 8 | 9 | PrintStr("DrvNum db "); 10 | PrintNum(header.BS_DrvNum); 11 | PrintStr(NEWLINE); 12 | 13 | PrintStr("Reserved1 db "); 14 | PrintNum(header.BS_Reserved1); 15 | PrintStr(NEWLINE); 16 | 17 | PrintStr("BootSig db 0x"); 18 | PrintHex(header.BS_BootSig); 19 | PrintStr(NEWLINE); 20 | 21 | PrintStr("VolID db "); 22 | PrintNum(header.BS_VolID); 23 | PrintStr(NEWLINE); 24 | 25 | PrintStr("VolLab db \""); 26 | PrintStrN(header.BS_VolLab,11); 27 | PrintChar('\"'); 28 | PrintStr(NEWLINE); 29 | 30 | PrintStr("FileSysType db \""); 31 | PrintStrN(header.BS_FileSysType,8); 32 | PrintChar('\"'); 33 | PrintStr(NEWLINE); 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /lab8/source/counter.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | string head = "#define RELEASE_TIMES "; 6 | string filename = "include/version.h"; 7 | int main(){ 8 | fstream fin(filename.c_str()); 9 | fin.seekg(head.size()); 10 | int v; 11 | fin >> v; 12 | ++v; 13 | cout << head << v << endl; 14 | fin.seekp(0,ios::beg); 15 | fin << head << v << endl; 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /lab8/source/fork1.cpp: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | #include "fork.h" 3 | 4 | int main(){ 5 | if (fork() == 0){ 6 | for (int i = 0;i < 20;++i){ 7 | PrintChar('.'); 8 | } 9 | }else{ 10 | if (fork() == 0){ 11 | for (int i = 0;i < 20;++i){ 12 | PrintChar('o'); 13 | } 14 | }else{ 15 | for (int i = 0;i < 20;++i){ 16 | PrintChar('x'); 17 | } 18 | } 19 | } 20 | PrintStr(NEWLINE); 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /lab8/source/fork2.cpp: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | #include "fork.h" 3 | 4 | ostream cout; 5 | int main(){ 6 | int i=0; 7 | for(i=0;i<3;i++){ 8 | uint8_t fpid=fork(); 9 | if(fpid==0) 10 | PrintStr("son", YELLOW); 11 | else 12 | PrintStr("FATHER",LGREEN); 13 | PrintStr(NEWLINE); 14 | } 15 | return 0; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /lab8/source/fruit.cpp: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | #include "thread.h" 3 | #include "sem.h" 4 | 5 | uint16_t count = 0; 6 | uint8_t sid; 7 | uint16_t fid[2]; 8 | bool useSem = true; 9 | uint16_t total = 50; 10 | 11 | __attribute__((regparm(1))) 12 | void * GiveFruit(void *p){ 13 | for (int i = 0;i < total / 2;++i){ 14 | if(useSem)semWait(sid); 15 | PrintNum(*(uint16_t*)(p), LBLUE);// 进入 16 | uint16_t old; 17 | old = count; 18 | for (uint16_t w=0;w<0xFFFF;++w){ 19 | for (uint16_t ww=0;ww<0xFF;++ww){ 20 | for (uint16_t www=0;www<0x1;++www){ 21 | } 22 | } 23 | } 24 | count = old + 1; 25 | PrintNum(count,RED); // 数字 26 | PrintNum(*(uint16_t*)(p),LGREEN); // 出来 27 | if(useSem)semSignal(sid); 28 | } 29 | return 0; 30 | } 31 | 32 | int main(){ 33 | thread_t tid[2]; 34 | sid = semCreate(1); 35 | fid[0] = 0; 36 | fid[1] = 1; 37 | 38 | thread_create(&tid[0],GiveFruit,&fid[0]); 39 | thread_create(&tid[1],GiveFruit,&fid[1]); 40 | thread_join(tid[0],0); 41 | thread_join(tid[1],0); 42 | PrintStr("I have "); 43 | PrintNum(count); 44 | PrintStr(" fruits, I should have "); 45 | PrintNum(total); 46 | PrintStr(NEWLINE); 47 | 48 | PrintStr("I don't use sem!\r\n",LGREEN); 49 | count = 0; 50 | useSem = 0; 51 | thread_create(&tid[0],GiveFruit,&fid[0]); 52 | thread_create(&tid[1],GiveFruit,&fid[1]); 53 | thread_join(tid[0],0); 54 | thread_join(tid[1],0); 55 | PrintStr("I have "); 56 | PrintNum(count); 57 | PrintStr(" fruits, I should have "); 58 | PrintNum(total); 59 | PrintStr(NEWLINE); 60 | 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /lab8/source/header.asm: -------------------------------------------------------------------------------- 1 | BITS 16 2 | 3 | [global _start] 4 | [extern main] 5 | 6 | jmp _start 7 | 8 | _start: 9 | push word 0 ; 由于G++的ret是32位的, 这里补0 10 | call main 11 | ;调用int 20h 12 | ;xor ax, ax 13 | ;mov es, ax 14 | ;mov di, 20h * 4 15 | ;pushf 16 | ;call far [es:di] 17 | sti 18 | int 20h 19 | jmp $ 20 | -------------------------------------------------------------------------------- /lab8/source/help.cpp: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | 3 | const char *HELP_INFO = "\ 4 | Input a 1~5 for parallel running. A stream nums for serial running \n\r\ 5 | Commands:\n\r\ 6 | r Go to look user processes\n\r\ 7 | ls list all programs\n\r\ 8 | cls Clear Screen\n\r\ 9 | uid See the id of current user\n\r\ 10 | top View running processes of current user\n\r\ 11 | topa View running processes of all user\n\r\ 12 | wake Wake a process, ex: wake 1\n\r\ 13 | suspend Suspend a process, ex: suspend 2\n\r\ 14 | pr Set the priority of a task ex: pr [pid] [priority]\n\r\ 15 | kill Kill a process, ex: kill 3\n\r\ 16 | killall Kill all Processes\n\r\ 17 | open Open a file\n\r\ 18 | file See the state of the file\n\r\ 19 | write Write data to the file\n\r\ 20 | read read data from the file\n\r\ 21 | seekg Set the pointer of getting file\n\r\ 22 | seekp Set the pointer of putting file\n\r\ 23 | uname Show os info\n\r\ 24 | Keys:\n\r\ 25 | Esc Back to Shell but not kill processes\n\r\ 26 | Ctrl+C Clear Screen\n\r\ 27 | Ctrl+Z Back to Shell and kill all processes\n\r\ 28 | Alt+Num Tab User: Alt+1 ALt+2 Alt+3 Alt+4\n\r\ 29 | "; 30 | 31 | int main(){ 32 | PrintStr(HELP_INFO,WHITE); 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /lab8/source/kan.asm: -------------------------------------------------------------------------------- 1 | ;My Name 2 | ;Jackie Wu (Wu Kan) 3 | ;14348134 4 | 5 | org 100H 6 | ;org 7c00h 7 | outDelay equ 40000 8 | inDelay equ 500 9 | 10 | ;set data segment 11 | mov ax,cs 12 | mov ds,ax 13 | 14 | ;text window 15 | ;25 * 80 16 | mov ax,0B800h 17 | mov es,ax 18 | 19 | %macro SETMEM 2 20 | mov ax,%2 21 | mov [%1],ax 22 | %endmacro 23 | 24 | START: 25 | call DELAY 26 | call SHOWINFO 27 | call DELAY 28 | 29 | SETMEM pos,1405H 30 | SETMEM vel,0FF01H 31 | mov cx,8 32 | call LINE 33 | 34 | SETMEM pos,1109H 35 | SETMEM vel,0001H 36 | mov cx,14 37 | call LINE 38 | 39 | SETMEM pos,1705H 40 | SETMEM vel,0001H 41 | mov cx,7 42 | call LINE 43 | 44 | SETMEM pos,1705H 45 | SETMEM vel,0100H 46 | mov cx,10 47 | call LINE 48 | 49 | SETMEM vel,0001H 50 | mov cx,7 51 | call LINE 52 | 53 | SETMEM pos,170BH 54 | SETMEM vel,0100H 55 | mov cx,10 56 | call LINE 57 | 58 | SETMEM pos,170DH 59 | SETMEM vel,0001H 60 | mov cx,8 61 | call LINE 62 | 63 | SETMEM pos,1615H 64 | SETMEM vel,0FF01H 65 | mov cx,2 66 | call LINE 67 | 68 | SETMEM pos,1B0DH 69 | SETMEM vel,0001H 70 | mov cx,10 71 | call LINE 72 | 73 | SETMEM pos,1F0DH 74 | SETMEM vel,0001H 75 | mov cx,9 76 | call LINE 77 | 78 | SETMEM vel,0100H 79 | mov cx,4 80 | call LINE 81 | 82 | SETMEM vel,00FFH 83 | mov cx,2 84 | call LINE 85 | 86 | call DELAY 87 | call DELAY 88 | call DELAY 89 | call DELAY 90 | call DELAY 91 | mov ax,3 92 | int 10h 93 | jmp START 94 | 95 | LINE: 96 | ;cx is the len of line 97 | LINELOOP: 98 | call DELAY 99 | call SHOW 100 | call MOVEPOS 101 | loop LINELOOP 102 | ret 103 | 104 | SHOWINFO: 105 | mov cx,[msgLen] 106 | 107 | mov si,message 108 | 109 | mov di, (1*80 + 1) * 2 110 | 111 | printChar: 112 | mov al,[si] 113 | inc si 114 | mov ah,07h 115 | mov [es:di],ax 116 | add di,2 117 | loop printChar 118 | ret 119 | 120 | DELAY: 121 | push cx 122 | mov cx, outDelay 123 | LOOP1: 124 | mov ax, inDelay 125 | LOOP2: 126 | dec ax 127 | jg LOOP2 128 | loop LOOP1 129 | pop cx 130 | 131 | ret 132 | 133 | MOVEPOS: 134 | mov ax,[pos] 135 | mov bx,[vel] 136 | add ah,bh 137 | add al,bl 138 | mov [pos],ax 139 | ret 140 | 141 | SHOW: 142 | push cx 143 | mov bx,[pos] 144 | mov ax,0 145 | mov al,bl 146 | mov dx,80 147 | mul dx 148 | mov dx,0 149 | mov dl,bh 150 | add ax,dx 151 | mov cx,2 152 | mul cx 153 | mov bx, ax 154 | 155 | mov al,[char] 156 | inc al 157 | cmp al,'Z' 158 | jna LESSZ 159 | mov al,'A' 160 | LESSZ: 161 | mov [char],al 162 | mov ah,[color] 163 | and ah,0Fh 164 | inc byte[color] 165 | mov [es:bx],ax 166 | pop cx 167 | ret 168 | 169 | DATA: 170 | message db "My Name is" 171 | msgLen dw $-message 172 | 173 | pos dw 0000h 174 | vel dw 0000h 175 | char db 'a' 176 | color db 09H 177 | 178 | times 510-($-$$) db 0 179 | dw 0xaa55 180 | -------------------------------------------------------------------------------- /lab8/source/letter.cpp: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | #include "thread.h" 3 | 4 | char str[80]="129djwqhdsajd128dw9i39ie93i8494urjoiew98kdkd"; 5 | int LetterNr=0; 6 | 7 | __attribute__((regparm(1))) 8 | void* Count(void *){ 9 | for (int i = 0;str[i];++i){ 10 | if (str[i] >= 'a' && str[i] <= 'z')LetterNr++; 11 | } 12 | return (void*)LetterNr; 13 | } 14 | 15 | int main(){ 16 | thread_t tid; 17 | thread_create(&tid, Count, 0); 18 | thread_join(tid, 0); 19 | PrintStr("#Alpha of Str: "); 20 | PrintNum(LetterNr); 21 | PrintStr(NEWLINE); 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /lab8/source/linker_100.ld: -------------------------------------------------------------------------------- 1 | ENTRY(main); 2 | SECTIONS 3 | { 4 | . = 0x100; 5 | .text : AT(0x100) 6 | { 7 | _text = .; 8 | *(.text); 9 | _text_end = .; 10 | } 11 | .data : 12 | { 13 | _data = .; 14 | *(.bss); 15 | *(.bss*); 16 | *(.data); 17 | *(.rodata*); 18 | *(COMMON) 19 | _data_end = .; 20 | } 21 | /DISCARD/ : 22 | { 23 | *(.note*); 24 | *(.iplt*); 25 | *(.igot*); 26 | *(.rel*); 27 | *(.comment); 28 | /* add any unwanted sections spewed out by your version of gcc and flags here */ 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /lab8/source/ls.cpp: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | #include "disk.h" 3 | 4 | char buf[512]; 5 | Entry e; 6 | 7 | const char Months[12][4] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}; 8 | 9 | __attribute__((regparm(1))) 10 | void PrintDate(uint16_t date){ 11 | //Month 12 | uint8_t month = (date >> 5) & 0xF; 13 | PrintStr(Months[month - 1]); 14 | PrintChar('.'); 15 | uint8_t day = (date) & 0x1F; 16 | PrintNum(day); 17 | PrintChar(','); 18 | uint16_t year = uint16_t((date >> 9) & 0x7F) + 1980; 19 | PrintNum(year); 20 | } 21 | 22 | __attribute__((regparm(1))) 23 | void Print2Num(int num){ 24 | PrintChar(num / 10 + '0'); 25 | PrintChar(num % 10 + '0'); 26 | } 27 | 28 | __attribute__((regparm(2))) 29 | void PrintTime(uint16_t t,uint8_t offset){ 30 | uint8_t second = (t & 0x1F) * 2; 31 | uint8_t minute = ((t>>5) & 0x3F); 32 | uint8_t hour = (((t>>11) & 0x1F) + offset)%24; 33 | Print2Num(hour); 34 | PrintChar(':'); 35 | Print2Num(minute); 36 | PrintChar(':'); 37 | Print2Num(second); 38 | } 39 | 40 | char dbuf[1024]; 41 | __attribute__((regparm(1))) 42 | uint16_t GetNextCluster(uint16_t u){ 43 | //get fat 44 | int t = u * 3 / 2; 45 | int p = t / 512; 46 | int o = t % 512; 47 | ReadFloppy(1 + p,2,dbuf); 48 | //uint16_t w = ((buf[o+1]&0xFF) << 8) | (buf[o]&0xFF); 49 | //注意位扩展:-( 50 | uint16_t w = *(uint16_t*)(dbuf + o); 51 | if (u % 2 == 0){ 52 | w &= 0xFFF; 53 | }else{ 54 | w = (w >> 4) & 0xFFF; 55 | } 56 | return w; 57 | } 58 | 59 | __attribute__((regparm(1))) 60 | void PrintClusters(uint16_t u){ 61 | PrintNum(u); 62 | u = GetNextCluster(u); 63 | for(int i = 0;i < 5 &&(!(u >= 0xFF8));++i){ 64 | PrintChar(','); 65 | PrintNum(u); 66 | u = GetNextCluster(u); 67 | } 68 | if (!(u >= 0xFF8)){ 69 | PrintStr(",..."); 70 | } 71 | } 72 | int main(){ 73 | 74 | bool first = true; 75 | for (int i = 19;i < 19 + 14;++i){ 76 | ReadFloppy(i,1,buf); 77 | for (int j = 0;j < 512/32;++j){ 78 | for (int k = 0;k < 32;++k){ 79 | *(((char*)&e) + k) = buf[k + j*32]; 80 | } 81 | //空文件,E5标记的跳过 82 | if (e.DIR_Name[10] == 0 || uint8_t(e.DIR_Name[0]) == 0xE5)continue; 83 | if (first){ 84 | first = false; 85 | PrintStr("Filename Size Date Time(UTC+8) Clusters",LBLUE); 86 | PrintStr(NEWLINE); 87 | } 88 | //Print Name 89 | int count = 0; 90 | for (int i = 0;i < 8;++i){ 91 | if(e.DIR_Name[i] && e.DIR_Name[i] != ' '){ 92 | PrintChar(e.DIR_Name[i]); 93 | ++count; 94 | } 95 | else break; 96 | } 97 | PrintChar('.'); 98 | for (int i = 8;i < 11;++i){ 99 | if(e.DIR_Name[i] && e.DIR_Name[i] != ' '){ 100 | PrintChar(e.DIR_Name[i]); 101 | ++count; 102 | } 103 | else break; 104 | } 105 | for (int i = count;i < 12;++i)PrintChar(' '); 106 | count = PrintNum(e.DIR_FileSize); 107 | for(int i = count;i < 6;++i)PrintChar(' '); 108 | PrintDate(e.LAST_WrtDate); 109 | PrintChar(' '); 110 | //使用东八区时间 111 | PrintTime(e.LAST_WrtTime, 8); 112 | //Print Clusters 113 | PrintStr(" "); 114 | PrintClusters(e.DIR_FstClus); 115 | PrintStr(NEWLINE); 116 | } 117 | } 118 | 119 | return 0; 120 | } 121 | -------------------------------------------------------------------------------- /lab8/source/mat.cpp: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | #include "thread.h" 3 | 4 | const int M = 3; 5 | const int K = 2; 6 | const int N = 3; 7 | const int NUM_THREADS = M * N; 8 | int A[M][K]={{1,4},{2,5},{3,6}}; 9 | int B[K][N]={{8,7,6},{5,4,3}}; 10 | int C[M][N]; 11 | 12 | struct RC{ 13 | int r,c; 14 | }; 15 | 16 | RC data[NUM_THREADS]; 17 | 18 | __attribute__((regparm(1))) 19 | void* CalcOneElem(void* i){ 20 | RC rc = *(RC*)i; 21 | int r = rc.r; 22 | int c = rc.c; 23 | C[r][c] = 0; 24 | for (int i = 0;i < K;++i){ 25 | C[r][c] += A[r][i] * B[i][c]; 26 | } 27 | return 0; 28 | } 29 | 30 | 31 | __attribute__((regparm(3))) 32 | void PrintMat(int *a, int r, int c){ 33 | for (int _r = 0;_r < r;++_r){ 34 | PrintStr(" "); 35 | for (int _c = 0;_c < c;++_c){ 36 | PrintNum(a[_r * c + _c]); 37 | PrintChar(' '); 38 | } 39 | PrintStr(NEWLINE); 40 | } 41 | } 42 | 43 | int main(){ 44 | thread_t tid[NUM_THREADS]; 45 | for (int i = 0;i < M;++i){ 46 | for (int j = 0;j < N;++j){ 47 | int id = i * N + j; 48 | data[id].r = i; 49 | data[id].c = j; 50 | thread_create(&tid[id],CalcOneElem,&data[id]); 51 | } 52 | } 53 | //等待所有线程结束 54 | for (int i = 0;i < NUM_THREADS;++i){ 55 | thread_join(tid[i],0); 56 | } 57 | PrintMat((int*)A,M,K); 58 | PrintStr(" X\r\n",GREEN); 59 | PrintMat((int*)B,K,N); 60 | PrintStr("The result is: \r\n"); 61 | PrintMat((int*)C,M,N); 62 | PrintStr(NEWLINE); 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /lab8/source/screen.cpp: -------------------------------------------------------------------------------- 1 | #include "disk.h" 2 | 3 | char buf[80 * 25]; 4 | File f; 5 | char filename[12] = "SCREEN.TXT"; 6 | int main(){ 7 | open(&f, filename); 8 | asm volatile("push es;"); 9 | asm volatile("mov es, ax;"::"a"(0xB800)); 10 | for (int i = 0;i < 80*25;++i){ 11 | asm volatile( 12 | "mov ax, es:[bx];" 13 | :"=a"(buf[i]) 14 | :"b"(i * 2) 15 | ); 16 | } 17 | asm volatile("pop es;"); 18 | write(&f, buf, 80 * 25); 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /lab8/source/testnew.cpp: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | #include "memory.h" 3 | 4 | int main(){ 5 | mem_init(); 6 | int *a = new int; 7 | if (a != mem_null){ 8 | *a = 10; 9 | PrintNum((uint16_t)(unsigned long)a,RED); 10 | PrintNum(*a); 11 | delete a; 12 | a = new int; 13 | *a = 30; 14 | PrintNum((uint16_t)(unsigned long)a,GREEN); 15 | PrintNum(*a); 16 | PrintStr(NEWLINE); 17 | delete a; 18 | a = new int[100]; 19 | if (a == mem_null){ 20 | PrintStr("Lack of Memory!"); 21 | return 0; 22 | } 23 | a[0] = 1; 24 | a[1] = 1; 25 | for (int i = 2;i < 20;++i){ 26 | a[i] = a[i-1] + a[i-2]; 27 | } 28 | for (int i = 0;i < 20;++i){ 29 | PrintNum(a[i]); 30 | PrintChar(','); 31 | } 32 | }else{ 33 | PrintStr("Lack of Memory!"); 34 | } 35 | PrintStr(NEWLINE); 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /lab8/source/testport.cpp: -------------------------------------------------------------------------------- 1 | #include "port.h" 2 | 3 | char GoodJob[32] = "GoodJob!"; 4 | int main(){ 5 | WritePort(TALK_PORT,GoodJob,32); 6 | SetPortMsgV(TALK_PORT,1); 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /lab8/source/testst.cpp: -------------------------------------------------------------------------------- 1 | void havepar(){ 2 | int a = 2; 3 | int b = a + 3; 4 | } 5 | 6 | void ww(){ 7 | havepar(); 8 | } 9 | -------------------------------------------------------------------------------- /toShirley.asm: -------------------------------------------------------------------------------- 1 | ;To Shirley 2 | ;Jackie Wu (Wu Kan) 3 | ;2016-03-01 4 | 5 | outDelay equ 50000 6 | inDelay equ 2400 7 | 8 | ;set data segment 9 | mov ax,07c0h 10 | mov ds,ax 11 | 12 | ;text window 13 | ;25 * 80 14 | mov ax,0B800h 15 | mov es,ax 16 | 17 | %macro SETMEM 2 18 | mov ax,%2 19 | mov [%1],ax 20 | %endmacro 21 | 22 | START: 23 | call DELAY 24 | call SHOWINFO 25 | call DELAY 26 | 27 | SETMEM pos,1107H 28 | SETMEM vel,0001H 29 | mov cx,14 30 | call LINE 31 | 32 | SETMEM pos,1015H 33 | SETMEM vel,0FFFFH 34 | mov cx,2 35 | call LINE 36 | 37 | SETMEM pos,0F0CH 38 | SETMEM vel,0FF01H 39 | mov cx,5 40 | call LINE 41 | 42 | SETMEM pos,130CH 43 | SETMEM vel,0101H 44 | mov cx,5 45 | call LINE 46 | 47 | SETMEM pos,1D07H 48 | SETMEM vel,0100H 49 | mov cx,13 50 | call LINE 51 | 52 | SETMEM pos,1E0AH 53 | SETMEM vel,0001H 54 | mov cx,12 55 | call LINE 56 | 57 | SETMEM pos,1E0AH 58 | SETMEM vel,0100H 59 | mov cx,11 60 | call LINE 61 | 62 | SETMEM pos,280AH 63 | SETMEM vel,0001H 64 | mov cx,11 65 | call LINE 66 | 67 | SETMEM pos,2715H 68 | SETMEM vel,0FFFFH 69 | mov cx,2 70 | call LINE 71 | 72 | 73 | SETMEM pos,2307H 74 | SETMEM vel,0001H 75 | mov cx,15 76 | call LINE 77 | 78 | SETMEM pos,200DH 79 | SETMEM vel,0101H 80 | mov cx,2 81 | call LINE 82 | 83 | SETMEM pos,2011H 84 | SETMEM vel,0101H 85 | mov cx,2 86 | call LINE 87 | 88 | SETMEM pos,250DH 89 | SETMEM vel,0101H 90 | mov cx,2 91 | call LINE 92 | 93 | SETMEM pos,2511H 94 | SETMEM vel,0101H 95 | mov cx,2 96 | call LINE 97 | 98 | jmp $ 99 | 100 | LINE: 101 | ;cx is the len of line 102 | LINELOOP: 103 | call DELAY 104 | call SHOW 105 | call MOVEPOS 106 | loop LINELOOP 107 | ret 108 | 109 | SHOWINFO: 110 | mov cx,[msgLen] 111 | 112 | mov si,message 113 | 114 | mov di, 0*80 + 0 115 | 116 | printChar: 117 | mov al,[si] 118 | inc si 119 | mov ah,07H 120 | mov [es:di],ax 121 | add di,2 122 | loop printChar 123 | ret 124 | 125 | DELAY: 126 | push cx 127 | mov cx, outDelay 128 | LOOP1: 129 | mov ax, inDelay 130 | LOOP2: 131 | dec ax 132 | jg LOOP2 133 | loop LOOP1 134 | pop cx 135 | 136 | ret 137 | 138 | MOVEPOS: 139 | mov ax,[pos] 140 | mov bx,[vel] 141 | add ah,bh 142 | add al,bl 143 | mov [pos],ax 144 | ret 145 | 146 | SHOW: 147 | push cx 148 | mov bx,[pos] 149 | mov ax,0 150 | mov al,bl 151 | mov dx,80 152 | mul dx 153 | mov dx,0 154 | mov dl,bh 155 | add ax,dx 156 | mov cx,2 157 | mul cx 158 | mov bx, ax 159 | 160 | mov al,[char] 161 | mov ah,[color] 162 | mov [es:bx],ax 163 | pop cx 164 | ret 165 | 166 | DATA: 167 | message db "To Shirley" 168 | msgLen dw $-message 169 | 170 | pos dw 0000h 171 | vel dw 0000h 172 | char db 'a' 173 | color db 09H 174 | 175 | times 510-($-$$) db 0 176 | dw 0xaa55 177 | -------------------------------------------------------------------------------- /wkcn.asm: -------------------------------------------------------------------------------- 1 | ;Running Ball 2 | ;Jackie Wu (Wu Kan) 3 | ;14348134 4 | ;wkcn@live.cn 5 | 6 | ;totalDelay = outDelay * inDelay 7 | outDelay equ 50000 8 | inDelay equ 1800 9 | 10 | MAX_X equ 80 11 | MAX_Y equ 25 12 | 13 | ;set data segment 14 | mov ax,07c0h 15 | mov ds,ax 16 | 17 | ;text window 18 | ;25 * 80 19 | mov ax,0B800h 20 | mov es,ax 21 | 22 | 23 | %macro SINGLE 4 24 | ;pos dw 0000h ;from 0,0 25 | ;vel dw 0101h ;v = (1,1) 26 | ;char db '*' 27 | ;color db 07H 28 | 29 | mov ax, [%1] 30 | mov [pos], ax 31 | mov ax, [%2] 32 | mov [vel], ax 33 | mov al, [%3] 34 | mov [char], al 35 | mov al, [%4] 36 | mov [color], al 37 | 38 | call PLAY 39 | 40 | mov ax, [pos] 41 | mov [%1], ax 42 | mov ax, [vel] 43 | mov [%2], ax 44 | %endmacro 45 | 46 | START: 47 | call DELAY 48 | call PLAY 49 | SINGLE pos1,vel1,char1,color1 50 | SINGLE pos2,vel2,char2,color2 51 | SINGLE pos3,vel3,char3,color3 52 | call SHOWNAME 53 | jmp START 54 | 55 | PLAY: 56 | call SETPOINTER 57 | call ELIMINATE 58 | 59 | call UPDATEPOS 60 | 61 | call SETPOINTER 62 | call SHOW 63 | ret 64 | 65 | SHOWNAME: 66 | mov cx,[msgLen] 67 | 68 | mov si,message 69 | 70 | mov di, 10*80 + 30 71 | 72 | printChar: 73 | mov al,[si] 74 | inc si 75 | mov ah,07H 76 | mov [es:di],ax 77 | add di,2 78 | loop printChar 79 | 80 | ret 81 | 82 | DELAY: 83 | mov cx, outDelay 84 | LOOP1: 85 | mov ax, inDelay 86 | LOOP2: 87 | dec ax 88 | jg LOOP2 89 | loop LOOP1 90 | 91 | ret 92 | 93 | UPDATEPOS: 94 | ;parameter: pos, vel 95 | mov ax,[pos] 96 | mov bx,[vel] 97 | 98 | ;update x 99 | add ah,bh 100 | jne XNZ 101 | ;if x == 0 102 | mov bh,1 103 | XNZ: 104 | CMP ah,MAX_X-1 105 | jl XNF 106 | ;if x >= MAX_X-1 107 | mov bh,-1 108 | XNF: 109 | 110 | ;update y 111 | add al,bl 112 | jne YNZ 113 | ;if y == 0 114 | mov bl,1 115 | YNZ: 116 | CMP al,MAX_Y-1 117 | jl YNF 118 | ;if y >= MAX_Y-1 119 | mov bl,-1 120 | YNF: 121 | mov [pos],ax 122 | mov [vel],bx 123 | ret 124 | 125 | SETPOINTER: 126 | ;parameter pos, char 127 | mov ax, 0 128 | mov bx, [pos] ; bx = (x,y) 129 | mov al, bl 130 | mov cx, MAX_X 131 | mul cx ; ax *= MAX_X namely ax = y * MAX_X 132 | mov cx, 0 133 | mov cl, bh 134 | add ax, cx ; ax += x 135 | mov cx, 2 136 | mul cx 137 | mov bx, ax 138 | ret 139 | 140 | SHOW: 141 | ;old 142 | mov cx,[es:bx] 143 | mov si,[oldpt] 144 | ;mov [es:si],cx 145 | ;new 146 | mov al, [char] 147 | mov ah, [color] 148 | mov [es:bx],ax 149 | ret 150 | 151 | ELIMINATE: 152 | ;save bx 153 | mov [oldpt],bx 154 | ;clean 155 | mov ax, 0 156 | mov [es:bx],ax 157 | ret 158 | 159 | 160 | 161 | 162 | DATA: 163 | message db 'WuKan 14348134' 164 | msgLen dw $-message 165 | 166 | outCount dw outDelay 167 | inCount dw inDelay 168 | 169 | pos dw 0000h ;from 0,0 170 | vel dw 0101h ;v = (1,1) 171 | char db '*' 172 | color db 07H 173 | 174 | oldpt dw 0000h; 175 | 176 | ;elements 177 | pos1 dw 0000h 178 | vel1 dw 0101h 179 | char1 db '*' 180 | color1 db 03H ;green 181 | 182 | pos2 dw 1010h 183 | vel2 dw 01FFh 184 | char2 db 'A' 185 | color2 db 0CFH ;twinkle red and light white 186 | 187 | pos3 dw 2019h 188 | vel3 dw 0FFFFh 189 | char3 db '@' 190 | color3 db 0EH ;yello 191 | 192 | times 510-($-$$) db 0 193 | dw 0xaa55 194 | --------------------------------------------------------------------------------