北大的CSAPP期末题说难不是很难,但是对于概念的理解要求还是很高的,所以要对概念做到会用以及尽可能深入的了解其过程。
所以在这里放一点容易遗忘的知识点供反复观看。
信息表示
int中0x8000 0000 的相反数还是他自己,是最小的负数。
浮点数
对于这部分的考察不止是IEEE754的背诵,更进一步的,北大通常考其更接近于一般性的理论以及你对于如何使用浮点格式去表达一个数字,因此要求我们牢固的掌握浮点数格式,以及其规格化表达和非规格化表达。
首先是三个部分的表达:
符号位
符号位一位表示正负。
阶码
阶码注意偏置常数(2^(n - 1) - 1).
尾数
尾数小数点前面隐含一个1.
所以还是放这张无敌的图上来:
放一点结论,减少指数位,用于小数部分,NAN更多,表示的实数值更少,指数小了能够表示的最大实数变小,最小实数变大,小数部分增加了精度会更高。
机器级代码
SUB和AND会改变条件码和寄存器的值,LEAL不改变条件码。
switch分支跳转汇编指令:jmp *.L3(,%eax,8)
相同寄存器即相关,但不一定冲突。
信号
SIGKILL和SIGSTOP信号既不能被捕获,也不能被忽略。
在任何时刻,一种类型至多只会有一个待处理信号。
当进程在前台运行时,键入CTRL+C,内核就会发送一个SIGINT信号给这个前台进程。
SIGCHLD信号只有在fork的子进程结束时产生。
存储
知道页块大小后,就可以推出每个页框中有多少个页表项,进而推出一级页表也已表示多少位地址。
高速缓存利用了时间局部性。
虚拟内存利用了空间局部性。
sum具有良好的时间局部性。
循环通常具有很好的时间局部性和空间局部性;
数组通常具有很好的空间局部性。
并发
在fork之后,父子进程共享之前的物理页,但权限都变为只读。
系统I/O
C语言中的标准I/O函数不是线程安全的。
避免缓冲区溢出带来的程序风险:
- 编程时避免使用gets,而采用fgets;
- 程序运行时随机化栈的偏移地址(只能很小范围的保护);
- 在硬件级别引入不可执行代码段的机制;
- 引入金丝雀;
printf所属的标准I/O是由缓冲区的,直到关闭文件、遇到换行符或者fflush时才会输出;write则没有缓冲区直接输出。
文件
结构体
记得对齐,结构体整体对齐。
链接
本地静态全局变量,在.data 中占有位置,不需要重定位,但出现在符号表中。
字符串出现在.rodata中。
其他文件中的函数引入时为弱符号,静态变量为local符号
异常
中断一定是异步发生的。
异常处理程序一定运行在内核模式下。
陷阱一定是同步发生的。
需要继续整理的东西:
信号功能;
CISC与RISC的区别;
指令的各个阶段进行的操作。
I/O函数操作;
非局部跳转;