概述
信息的表示和处理
浮点数
BG
IEEE
TODO为什么。。。
示例与性质
TODO这几张图非常值得细看
舍入、加法、乘法
舍入
乘法
加法
C语言
整数
位表示
注意指针
位级运算
布尔代数
移位运算
最后一句没看懂,如果是补码表示那确实都是了吧
整型数
表示
转换
扩展和截断
注意默认符号
整数运算
注意向零舍入
内存指针字符串表示
注意一直都是字节编址的
貌似IA32、Sun都是32位的
所以对于小端系统字符串读取就有点意思
程序的机器级表示
基础
8086CPU
结构
寄存器
数据和指针寄存器
标志寄存器
CF
ZF
SF
PF
OF
AF
段寄存器
指令系统
8086/8088的指令系统包含了六种类型,其中数据传送指令14条,算术运算指令20条,逻辑运算指令13条,串操作指令10条,控制转移指令28条,处理器控制指令12条。
寻址方式
存储器寻址花样比较多
IA32处理器体系结构
基本结构
寄存器
基本寄存器
就是启动那会儿的对吧
保护模式就是启动完了开启映射了
状态就是反应状态,控制就是可以用来控制CPU
注意标红的就行,注意奇偶标志的范围。跟8086差不多。
系统寄存器*
值得注意调试的也在!还有任务寄存器,应该就是进程虚拟地址之类的相关的了吧
浮点单元FPU*
内存管理*
TODO,这部分我打算之后再复习一下OS
实地址模式
保护模式
指令执行周期
程序如何运行
计算机如何启动
汇编语言
发展历程*
概述
汇编基础
寄存器
操作数和数据传送
不愧是CISC
寻址
比如说数组元素访问,a[2],其中Rb就是a的基址,Ri就是这个2,S就是sizeof(a[0])。D可能就是具体这个a[2]的某个字节了。
栈操作
算术和逻辑运算
我靠,注意这个leaq还可以作为这种计算算术表达式的操作,6666
怎么感觉有点沙比
66666
比较和跳转
布尔指令
这个牛逼
比较指令
跳转指令
Linux汇编程序
典中典
TODO 这里没懂
控制
流程控制:条件码
就是标志寄存器呗
注意这个访问条件码,新东西
感觉他这说得好谜语,总之意思大概就是根据条件码的值然后设置寄存器的值,比如说:
1 | cmp al, 0x05 ; 比较 AL 寄存器的值和立即数5 |
条件分支
(SF^OF)就是说除了 负数^溢出 这种情况,也即只有11和00的情况会被考虑,后者是普通情况,前者只有正数-负数这种情况会出现,而此时必定是大于。同时ZF代表排除==的情况。
然后,SF=1,OF=0表示的是相减负数,SF=0,OF=1表示的是负溢出,此时必定为负数-正数,所以必是小于。
而对于无符号数,只有在结果为负数,也即小于的情况会溢出,所以只需判断CF标志
确实
相当于是两个分支都算一遍,最后再用这个条件传送指令决定哪个是哪个
确实。。。
循环结构的实现
do-while
while
跳到中间
GCC的 -Og
选项是一种优化级别,旨在提供编译速度和运行时性能之间的平衡。这个选项从GCC 4.7版本开始引入,目的是在不牺牲太多编译速度的情况下,优化生成的代码以提高程序的运行效率。
- 优化级别:
-Og
通常提供比-O0
(没有优化)更高的优化级别,但低于-O1
、-O2
和-O3
。它专注于那些不太耗时且能够带来明显性能提升的优化。 - 调试友好:
-Og
选项生成的代码旨在保持与源代码的可读性和对应性,使得调试过程更加容易。这与-O0
类似,但-Og
仍然会应用一些优化,以提高程序的运行性能。
guarded-do
就是说又转化了一层
感觉像是在第一次进去的时候少了一次goto
for
for-while
for-dowhile
Switch语句
总结到位
6666
注意这个fall-through的处理
甚至还是在switch case里才初始化的w,也确实不是每个case都得初始化
过程
栈结构
这个内存管理应该指的是栈上不是堆上。。
调用约定
传递控制
传递数据
x86-64架构中常见的几个用于函数参数传递的寄存器:
- **
RDI
**:通常用作第一个整数或指针类型的函数参数。 - **
RSI
**:用作第二个整数或指针类型的函数参数。 - **
RDX
**:用作第三个整数或指针类型的函数参数。 - **
RCX
**:用作第四个整数或指针类型的函数参数。 R8
和 **R9
**:在需要更多参数的情况下,从这些寄存器开始。
所以多的参数是由后往前推的,返回地址最后推。
管理局部数据
就是说callee的参数其实理论上是叫放在caller的栈帧的
我去,简答题
寄存器保存约定
在x86-64位架构中,callee-saved registers通常包括:
- RBX,r12,r13,r14
- RSP(栈指针,如果被修改)
- RBP(基指针,如果被用作帧指针)
caller-save寄存器:
- RAX:用于存储函数的返回值。
- rdi/rsi/rdx/rcx/r8/r9:参数
- R10,R11:被调用过程可修改
递归
数据
数组
64位系统是吧
对,相当于A3是一个指向3*int的指针,然后A4其实就跟A2是一个道理,相当于*(A4[0])为int。
结构体
注意c后面还得7B的padding
浮点数*
高级主题
内存布局
巨长的data段。。
缓冲区溢出
安全隐患
攻击
防范
感觉看起来主要还是检查ra
联合union
处理器体系结构
指令集体系结构
概述
Y86-64
指令操作码包含8位,低4位指示具体操作类型fn
注意这个无寄存器含义
逻辑设计
概述
运算
存储
顺序执行处理器
回顾
SEQ实现
概述
指令具体步骤
译码会解析寄存器含义了
M是指令。
取指阶段会对指令进行解读,看出rA、rB、imm什么的都是指令的啥部位,同时会更新PC
译码阶段会读取寄存器值
注意这个执行,很有意思,设为0xF比直接中断好
硬件逻辑
流水线基础
基本设计
冒险
冒险处理
数据冒险
暂停
数据转发
加载使用冒险
控制冒险
控制组合
性能评估
CPI:执行每条指令所需的平均时钟周期数
注意这个算式,因为流水线执行,近似认为1个cycle一条指令
数据冒险可以用暂停和数据转发实现(想想就知道),加载使用必须插1个气泡,控制冒险插2个,ret插3个
优化程序性能
综述
编译器优化
各种优化方法
一般都是转为指针访问
66666
示例
基础优化
指令级并行
存储器层次结构
存储器层级结构与局部性
概述
存储器结构
读写操作
磁盘
结构
容量
磁盘容量的计算方法 容量 = 每个扇区可记录的字节数 x 扇区总数
时间
磁盘访问的平均读取时间 访问时间 = 寻道时间 + 平均旋转延迟 + 数据传输时间
平均旋转延迟就是假设每次转半圈,也即1/2 * (1/RPM)*60 秒
数据传输时间就是,转一圈时间 / 每圈扇区数,其中每圈扇区数 = 平均扇区数 / 磁道数
调度算法
与CPU交互
其他
局部性
66666说得很本质
高速缓冲器Cache
高速缓存存储器组织结构和操作
高速缓存对程序性能的影响
不命中率
这个不命中率的计算:
那就是说一个块可以放B/4个int,然后每隔B/4个int就会出现冲突不命中,这个时候就要加载进去就是1/B/4
存储器山
重新排列提高空间局部性
6666
不过这样的话,如果放宽到整个,那A依然还是不怎么那个的吧
所以感觉还是这个最好
使用块提高时间局部性
确实,养成好习惯
链接
总结
重定位
概述
目标文件及格式
步骤
符号解析
在默认情况下,gcc
使用一个叫做 “common” 的机制来处理未初始化的全局变量和静态变量。这种机制允许多个编译单元(例如多个源文件)共享同一个未初始化的全局变量或静态变量。然而,这可能导致一些不可预见的行为,尤其是在多线程环境中。
使用 -fno-common
选项可以关闭这种默认行为,强制 gcc
为每个使用未初始化全局变量或静态变量的编译单元创建一个唯一的符号。这样做可以避免潜在的共享问题,但可能会增加程序的内存使用量。
重定位
打包
静态链接
动态链接
库打桩机制
异常控制流
异常和进程
异常控制流
异常
概述
分类
举例
进程
进程控制
信号与非本地跳转
Shells
信号
非本地跳转
6666
虚拟内存
基本概念
地址空间
虚拟内存作用
缓存
碎片化
内存管理
内存保护
地址翻译
系统举例
内存映射
动态内存分配
基本概念
高级概念
显式空闲链表
分离空闲链表
垃圾收集
内存相关风险
系统级IO
Unix I/O
RIO包
读取文件元数据,共享和重定位
标准IO
666