CMU 15-213|Overview & Bits Representation

冯诺依曼架构

组成部分

最经典的计算机架构,包含五个重要组成部分

  • 存储器
  • 控制器
  • 运算器
  • 输入
  • 输出

现在的计算机也基本是基于这个架构的,只是运算器和控制器统一交由 CPU 来进行处理。

但是和冯诺依曼体系结构对应的当年还有一个叫做哈佛结构的:它和冯诺依曼架构最大的区别在于能够同时访问数据和指令,虽然哈佛结构很快就黯然退场了,但是如今在移动端市场流行的 ARM 架构也是由此演变而来。

设计缺陷

可以说如今计算机系统出现的诸多不稳定,是在冯诺依曼架构设计之初就注定的

缓存溢出可以执行攻击者预订好的程序(游戏机设备的 jailbreak 有些就来自于此)

甚至采用 返回导向编程 的堆栈溢出攻击,在出现之后长达十多年里,主流操作系统都毫无防范之力

在 CSAPP 的实验中,我们将会亲自体验一番漏洞攻击,黑客模拟器XD

这门课程的必要性

程序的执行不仅仅是编写代码这么简单,代码写的好并不代表最终的执行就会正常。

我们对于一个事物的认知决定了如何更好的利用这个事物。

程序的执行除了代码本身,还需要结合内存,缓存,运算器等等部件,同时编译器,计算机系统的其他概念也会影响程序的最终执行,这门课程可以让我们从里到外的理解程序到底是如何执行的,这样才能写出更好更高效的代码。

数据的机器级表示

无符号和有符号

他们所能表示的数之间的关系可以直观的看下图:

这里其实有一种偏移 bias 的感觉,那就是如果讨论表示范围,对于同一个二进制的数据,有符号和无符号数据范围存在一定的 bias

目前主流的编程语言,默认都是有符号数,为了便于保存负数,但是 c 提供了无符号的声明形式

1
2
int a_signed_number = -15213;
unsigned int a_unsigned_number = 15213U;

转换操作

无符号数和有符号数在计算机的底层硬件表示中都是二进制存在的,只是计算机针对我们理解的无符号和有符号解释的方式不同

因此转换操作本身并不会改变二进制数据的实际内容,改变的只是计算机解释当前数值的方式

在进行互相转换的时候需注意:如果同时出现有符号和无符号的运算/比较,计算机在解释的时候会统一转化为无符号来进行解析

运算和溢出

无论是无符号数还是有符号数,一旦用来表示数值的最高位发生了进位/超出了表达形式/改变了符号位,就会发生溢出

无符号数溢出

实际上是 mod 操作,因为无符号本身并不需要牺牲一个 bit 的位置来表示符号,因此如果超出数据范围了,例如 3 bit 下, 110+111 = 6+7 = 13 = 1101 ,但是由于只能存储三位,因此实际存储的数据只有 101 因此最终结果实际上只有 13%8 = 5

有符号数溢出

分为正溢出和负溢出两种

还是以 3 bit 举例,对于有符号数能表示的范围应当是 -4 ~ 3,以 011+010 = 3+2 = 5 = 101,但是在二进制的解释下最终结果是 -4+1 =-3,这种情况就是正溢出(我们认为的5超出了能表示的范围,虽然 bit 位数没有超出,但是有符号数解释的最高位符号位收到了影响,溢出为了负数

浮点数

浮点数的IEEE存储形式定义

规范化值

M默认心里有一个1,这个1不需要实际的编码位置,只需要默认心里记住


CMU 15-213|Overview & Bits Representation
http://example.com/2024/04/22/CMU-15-213-Overview-Bits-Representation/
作者
Noctis64
发布于
2024年4月22日
许可协议