shell-Challenge-实验报告
shell实现相对路径实现 在进程控制块中添加工作目录域char env_work_dir[1024];,并通过以下两个系统调用进行读取与修改 123int syscall_read_work_dir(void * dstva);int syscall_write_work_dir(void* srcva);// 工作目录初值为"/",并且fork出子进程继承父进程工作目录 实现相对路径与绝对路径的转换函数void walk_realtive_path(char* work_dir, char* cd_arg, char* ans); 无论传入的是相对路径还是绝对路径最终都转换为绝对路径输出 传入当前工作目录(系统调用获得), 传入的路径参数,最终转换为的绝对路径写入ans中; (一个难写的字符串替换函数) 实现open的相对路径支持 12345678910int open(const char *path_0, int mode) { char path[1024]; // absolute path char...
lab6-实验报告
ThinkingThinking 6.1 示例代码中,父进程操作管道的写端,子进程操作管道的读端。如果现在想 让父进程作为“读者”,代码应当如何修改? 1234567891011121314151617181920212223242526272829#include <stdlib.h>#include <unistd.h>int fildes[2];char buf[100];int status;int main(){ status = pipe(fildes); if (status == -1) { printf("error\n"); } switch (fork()) { case -1: break; case 0: /*子进程-作为管道的写者*/ close(fildes[0]); /*关闭不用的读端*/ write(fildes[1], "Hello...
lab5-实验报告
ThinkingThinking 5.1 如果通过 kseg0 读写设备,那么对于设备的写入会缓存到 Cache 中。这是 一种错误的行为,在实际编写代码的时候这么做会引发不可预知的问题。请思考:这么做 这会引发什么问题?对于不同种类的设备(如我们提到的串口设备和IDE磁盘)的操作会 有差异吗?可以从缓存的性质和缓存更新的策略来考虑。 由于cache更新不及时等问题,可能在访问内核时错误读取到设备内容 例如外设发生内容改变,但是cpu不会吧这个改变直接写入cache,导致下一次从cache读取设备内容读取到未更新的值而错误 串口设备由于即时性与高使用频率,比IDE设备更加可能出现此类错误 Thinking 5.2 查找代码中的相关定义,试回答一个磁盘块中最多能存储多少个文件控制块?一个目录下最多能有多少个文件?我们的文件系统支持的单个文件最大为多大? 123#define PAGE_SIZE 4096#define FILE_STRUCT_SIZE 256#define BLOCK_SIZE PAGE_SIZE 一个磁盘块最多能容纳文件控制块 4096/256...
lab4-实验报告
ThinkingThinking 4.1内核在保存现场的时候是如何避免破坏通用寄存器的? 在陷入内核后PC指向了exc_gen_entry,在其中首先调用了SAVE_ALL宏,SAVE_ALL宏将所有寄存器保存在内核栈中。并在异常处理程序结束前调用RESTORE_ALL将保存的所有通用寄存器值恢复。 系统陷⼊内核调⽤后可以直接从当时的 $a0-$a3 参数寄存器中得到⽤户调⽤ msyscall 留下的信息吗? 可以。msyscall函数被调用时候,$a0-$a3中存储了前四个参数,在执行syscall并陷入内核到执行sys_*过程中,参数寄存器并不会发生改变。(不过在SAVE_ALL中这几个寄存器的值也被保存了) 我们是怎么做到让 sys 开头的函数“认为”我们提供了和用户调⽤ msyscall...
lab3-实验报告
ThinkingThinking 3.1 请结合MOS中的页目录自映射应用解释代码中e->env_pgdir[PDX(UVPT)] = PADDR(e->env_pgdir) | PTE_V 的含义。 A:使得env_pgdir对应的二级页表结构中虚拟地址UVPT对应存储一级页表地址 Thinking 3.2 elf_load_seg 以函数指针的形式,接受外部自定义的回调函数 map_page。 请你找到与之相关的data这一参数在此处的来源,并思考它的作用。没有这个参数可不可 以?为什么? A:data在此处的来源为load_icode,也就是进程控制块的指针。不可以没有这个参数。如果没有,回调函数中无法通过进程控制块获取页目录地址以及asid。 Thinking 3.3 结合 elf_load_seg...
lab2-实验报告
THINKINGThinking 2.1Q::在编写的 C 程序中,指针变量中存储的地址 被视为虚拟地址,还是物理地址?MIPS 汇编程序中 lw和sw 指令使用的地址被视为虚 拟地址,还是物理地址? **A:**均为虚拟地址 Thinking 2.2Q2.2.1 从可重用性角度阐述用宏实现链表的好处 A:使用宏实现链表的优势在于代码的泛化能力与模块化设计。宏既实现了函数模块化和代码复用的功能,同时可以通过参数化传递数据类型或者结构体名称,使得链表不依赖与某种具体的数据类型 Q2.2.2 分析include/queue.h 中单向链表、循环链表和双向链表在插入与删除操作上的性能差异 A: 单项链表:只可以获取当前项的下一项 插入:可以在某一元素之后与链表头部直接插入(O(1)),若需要在某一项前面插入,需要遍历页表 (O(n)) 删除:遍历删除 双向链表:可以获取某一项的前后两项 在某一元素前后插入和删除的时间复杂度都是(O(1)) 循环链表:插入和删除同单向链表 三种链表查询效率均为(O(n)) Thinking...
lab1-实验报告
Thingking 1.3Q: Thinking 1.1 在阅读 附录中的编译链接详解 以及本章内容后,尝试分别使用实验环境中 的原生 x86 工具链(gcc、ld、readelf、objdump 等)和 MIPS 交叉编译工具链(带有 mips-linux-gnu- 前缀,如 mips-linux-gnu-gcc、mips-linux-gnu-ld),重复其中的编译和解析过程,观察相应的结果,并解释其中向objdump传入的参数的含义。 A: 我们对于示例代码test_hello.c进行测试 123456#include <stdio.h>int main() { printf("Hello, World!\n"); return 0;} 使用原生工具链 123gcc -o test_hello test_hello.creadelf -h test_helloobjdump -d test_hello 利用readelf查看文件头信息得到: 反汇编得到 MIPS...
lab0-实验报告
ThinkingThinking 0.1Q: 对于README.txt文件,在初次创建并提交后与再次修改之后git status的状态的不同A: 二者git status之后的结果不同。第一次add之前显示的是未跟踪的文件,属于Untractked状态,原因是我们的文件没有被add过,没有提交到暂存区过。而commit之后再做修改,显示尚未暂存以备提交的变更,属于Modified状态,原因是我们已经commit到暂存区且之后又做了修改。 Thinking 0.2Q: Add the file、 statge the file 与commit分别对应哪条命令?A: Add the file对应 git add <文件>命令 stage the file 对应的也是git add <文件>命令 commit对应是 git commit -m "comment" Thinking 0.3Q1: 代码文件print.c被错误删除时,应当使用什么命令将其恢复?A1: git checkout --...
BUAA_OO_Unit4 UML与正向建模
BUAA_OO_Unit4 UML与正向建模 先来简单回顾一下本单元完成的任务:利用UML进行正向建模,并完成一个小型的图书馆管理系统 hw13:实现借阅,预约,预约取书,还书等基本流程 hw14:...
BUAA_OO_Unit3_JML规格化开发
本单元我们学习了JML规格化语言,并据此实现一个简单的社交网络。我们首先来简单回顾一下三次迭代开发的任务: 新建Person、Network、Tag类维护一个简单社交网络,并通过标签来管理存在关系的其他用户。 新增OfficialAccount类,实现公众号与文章发布推送功能 新增Message类及其子类,实现消息收发机制 架构设计hw9UML类图 容器选择在作业实现中存在许多person和tag容器中的查询操作,为了提升查询效率。我选择了HashMap作为容器,通过键值对查询提高查询效率,时间复杂度为O(1) 变量维护策略在社交网络中,存在许多query查询操作。如果每次查询都重新计算query所需要的特征值,可能会带来大量的循环操作,增强超时风险。我们可以将所需要的特征值存储起来,数据变化时对特征值进行相应修改,查询时直接返回对应的特征值,降低时间复杂度。 动态维护 query_tag_age_var...