ECNU 计算机系统 (CSAPP) 教材习题作业答案集

这里是华东师范大学计算机系统的作业答案。由于几乎每一年布置的习题都几乎相同,网上的答案又比较分散,就把自己上学期提交的作业pdf放上来了,供参考。 Download Link:http://cloud.billc.io/s/pk9pfAkcyF8br9E 另外,如果你需要LAB2-LAB4的实验报告的话,也可以翻阅我之前的博客,希望能够帮上打算进行肝脏爆破的你。 实在是不知道这个博客能放一些什么东西了。这学期选了三门专选,每天都在为作业奔波,想写的很多博客都没有时间完成。后面有空的话,把其他科目的作业也整理一下放上来好了。

September 23, 2019 · Bill Chen

深入理解计算机系统 (CS:APP) - 高速缓存实验 Cache Lab 解析

这个实验是这学期的第四个实验。作为缓存这一章的配套实验,设计得非常精妙。难度上来讲,相比之前的修改现成文件,直接写一个程序也更高了一些。需要注意的是检查程序在编译时开启了 -Werror,需要保证没有警告才能成功编译。 从官方文档得知需要完善 csim.c 和 trans.c 文件,第一个是模拟一个高速缓存的程序并从由 valgrind 程序生成的 trace 文件中统计 hit, miss 和 eviction 的数量。第二个文件需要优化矩阵转置程序降低程序的不命中度。 PART A 这一部分的核心是使用了一个结构体来模拟一个缓存行: typedef struct { int valid; ulong tag; clock_t time; } CacheLine; 再通过把缓存行在内存中动态分配成一个二维数组,实现模拟缓存的功能。并且使用了typedef CacheLine *CacheSet; 和 typedef CacheSet *CacheHead; 来让程序更整齐。输入来源于文件和命令行参数。可以用 getopt() 函数来解析参数。 各个函数的作用如下: CacheHead CacheInit(int S, int E) 为缓存动态分配内存; int CacheJudge(CacheHead cache, ulong index, ulong tag) 判断缓存状态,是否有效,标记匹配; void CacheEvict(CacheHead cache, ulong index, ulong tag) 执行 eviction 操作; void CacheTouch(CacheHead cache, ulong index, ulong tag) 执行读取操作,只更新时间戳; void CacheInsert(CacheHead cache, ulong index, ulong tag) 执行缓存写入操作; void Adder(int type, int num) 计数器,增加 hit, miss 和 eviction 的数量,并根据配置选择打印信息; void printByte(bytept h, int len) 逐字节以 16 进制打印内存数据; void Execute(CacheHead cache, char type, ulong address, int len) 主要的执行函数; int main(int argc, char *args[]) main 函数,读取参数,打开文件; 完整的程序代码如下:...

May 22, 2019 · Bill Chen

深入理解计算机系统 (CS:APP) 缓冲区漏洞实验 – Buffer Lab 解析

写在前面 这是 CSAPP 官网上的第 4 个实验 buflab,也是学校要求的第三个实验。这个实验比上一个单纯考查汇编语言使用的 Bomblab 要难许多,需要认真理解一下程序运行时对栈帧的操作。对于自学的学生,可以前往 http://csapp.cs.cmu.edu/3e/labs.html 下载,下载后能得到一个很详细的 pdf 文档,需要认真阅读才能知道作者想让我们干什么。做这个实验同样也啃了很久,花了十多个小时,不过也的确是对运行时栈的理解深刻了许多。 通过阅读官方文档,bufbomb 在运行时会调用 getbuff 函数: /* Buffer size for getbuf */ #define NORMAL_BUFFER_SIZE 32 int getbuf() { char buf[NORMAL_BUFFER_SIZE]; Gets(buf); return 1; } 缓冲区大小为32。一旦输入的字符超出32个就会出现segmentation fault,导致程序出现异常。而目标就是让程序出现异常,执行一些常规以外的代码。 这个实验就是利用程序溢出的漏洞来破解几个 level。 其中文件夹下的其他两个二进制文件hex2raw和makecookie分别用于将十六进制的字符数据转换成普通的字符串用于输入,和生成一个独一无二的cookie用于辨识作者。 根据官方文档,如果将答案存储在 exploit.txt 中,使用命令 cat exploit.txt | ./hex2raw | ./bufbomb -u bill 可以直接将字符串输入到 bomb 中验证答案。一个更有效的方法是: ./hex2raw < exploit.txt > exploit-raw.txt ./bufbomb -u bovik < exploit-raw.txt 文档中特别提醒到,每一个exploit.txt中的答案都应当以 0X0a 结尾,表示回车符结束输入。 在开始之前,使用objdump -d bufbomb > bufbomb....

May 7, 2019 · Bill Chen

深入理解计算机系统 (CS:APP) Lab2 - Bomb Lab 解析

写在前面 CS:APP是这学期的一门硬核课程,应该是目前接触到最底层的课程了。学校的教学也是尝试着尽量和CMU同步,课件和习题都直接照搬原版。包括现在着手的第二个实验室Bomb Lab。这个lab很有意思,没有提供全部c语言代码,需要手动根据反汇编语言推测在每一个阶段需要输入的内容,输入正确就可以进入下一个阶段。 理论上每个人获取到的lab都是不一样的,但对于自学学生而言在官网http://csapp.cs.cmu.edu/3e/labs.html下载到的实验室都是一样的,爆炸了之后也不会把信息发送到远程服务器扣分。 使用gdb bomb命令可以实时调试程序。结合break function、break *地址、disas、x/s $地址命令实时查看程序内的内容,同时用info registers和info frame查看寄存器信息和栈帧信息,可以拆除炸弹。 Phase 1 在Phase_1打下断点,使用info register可以得到寄存器信息: (gdb) info register rax 0x603780 6305664 rbx 0x0 0 rcx 0x3 3 rdx 0x1 1 rsi 0x603780 6305664 rdi 0x603780 6305664 rbp 0x402210 0x402210 <__libc_csu_init> rsp 0x7fffffffde28 0x7fffffffde28 r8 0x604674 6309492 r9 0x7ffff7fba540 140737353852224 r10 0x3 3 r11 0x7ffff7e015c0 140737352046016 r12 0x400c90 4197520 r13 0x7fffffffdf10 140737488346896 r14 0x0 0 r15 0x0 0 rip 0x400ee0 0x400ee0 <phase_1> eflags 0x206 [ PF IF ] cs 0x33 51 ss 0x2b 43 ds 0x0 0 es 0x0 0 fs 0x0 0 gs 0x0 0 得到汇编代码如下:...

April 18, 2019 · Bill Chen

Airport Simulation (数据结构与算法 - 队列 / Queue 的应用)

Airport Simulation 是数据结构与算法教材中用于演示Queue的一个小程序(大多数教师似乎会跳过这个练习)。主程序会通过输入总的运行时间、队列里可以等待的最多飞机数量,平均每个时间单元到来的飞机和离开的飞机(提供泊松分布的均值生成随机数)。 运行效果 程序的结构不算复杂,利用Runaway类来封装两个landing和takeoff队列,处理飞机的请求和行为;Plane类来封装飞机的状态和信息,以及在受到指令时输出信息到控制台。只是教材里的讲述有些分散,运行效果也由于输出太多而显得凌乱无比。练习布置许久之后也是一直没有找到一整块时间写完这个练习。这里是前几天完成的一个经过输出优化后的程序,格式比较易于观测。 该程序应在Linux或macOS下编译。在Windows下编译由于不支持彩色输出会出现一些奇怪的转移序列,sleep函数和usleep函数也应当用windows.h中提供的方法实现。 main.cpp和Random.h的源代码如下。其中Random.h用于提供泊松分布的随机数生成,参考自CSDN。 你可以在这里直接下载:https://cloud.billc.io/s/FeLekECBFKb6GkF #include <iostream>#include <queue>#include <unistd.h>#include "Random.h"using namespace std; typedef int feedback; const int success = 1; const int fail = 0; const int USPEED_SHORT = 1000; const int USPEED_LONG = 1000; enum flightStatus{ null, toLand, toTakeoff }; enum runawayAct{ idle, letTakeoff, letLand }; string percentage(int A, int B){ char *temp = new char[100]; sprintf(temp, "%3.2f%%", (double)A / (double)B * 100); string output = temp; return output; } class Plane{ private: int ID; int comingTime; flightStatus status; public: Plane(){ ID = -1; comingTime = -1; status = null; } Plane(int _ID, int _comingTime, flightStatus _status){ usleep(USPEED_SHORT); ID = _ID; comingTime = _comingTime; status = _status; cout << "[PLANE MESSAGE] Plane NO....

March 29, 2019 · Bill Chen