CS110 计算机体系结构 2 梦开始的地方
CS110 这门课本身讲述顺序相当合理,我将会大致沿用上课的顺序进行介绍,即和我的笔记大概一致。在少数我认为顺序不合理的地方,我会自行调整顺序,不过内容大致一致,因此读者只需要阅读本教程或笔记二者其一即可。
Great ideas in CA
本来想着把这个标题翻译成“计算机体系结构中的伟大思想”,但是又觉得有点画风突变的感觉,我不希望把 CA 做成像文科一样的课程。总之,如果你现在不理解以下这些内容也没关系——等到学完整个课程,你一定会有全新的认识。
- Abstraction (Layers of Representation / Interpretation) —— 抽象(表示/解释的分层)
- Moore’s Law (designing through trends) —— 摩尔定律(通过趋势进行设计)
- Make the common case fast (Amdahl’s Law) —— 让常见情况变快(阿姆达尔定律)
- Principle of locality (memory hierarchy) —— 局部性原理(内存层次结构)
- Parallelism (pipeline as special case) —— 并行性(流水线作为特例)
- Performance measurement and improvement —— 性能测量与提升
- Dependability via redundancy —— 通过冗余实现可靠性
顺带说一句,考试的时候会可能会涉及以上内容,请读者务必抄到 Cheatsheet 上。
这是整个课程梦开始的地方,最后我们会再回到这里的。会的。
C 语言
从哪里开始讲呢?我们按照从上至下的顺序,也就是从我们使用的高级程序设计语言之一:C语言,开始讲。
相信各位读者对于 C 语言的语法都很了解(否则请参考C 语言教程 | 菜鸟教程,不过这门课其实对 C 代码没有过高的要求,能看懂、区分出各类 UB,CE 和 RTE 即可)。作为几乎在所有平台上都能使用的语言,C 语言有更完整的变量类型定义、更好的内存管理,需要经过编译过程执行。接下来我们先简单复习一下 C 语言的内存管理相关内容。这些内容可能看上去有些碎片化,不过还请读者挑选其中记不熟的内容抄到 Cheatsheet 上。
C 语言的一些基础知识
严格来说,C 语言的指针类型大小是和系统有关的,但是方便起见,我们在本课程中统一指针大小为 4 byte,即 32 位——这就是我们常说的“32位计算机”里的“32位”的来源——32 bit 长度的地址。一般的计算机是 byte addressing 的,即每个确定的地址(如 0x1145DCBC)对应内存里的一个确定的字节。
一般来说,C 语言中的数组和指针是等效的(如 ar[2] 等效于 *(ar+2)),但是也有例外:
1 | char string1[] = "abc"; // 可以修改 |
在字符串中,存储时一般会在字符串尾部添加 \0 来标记字符串长度,但是也有特例:
1 | char s[] = "abc", t[3] = "abc"; |
回到数组,主函数传参时,采用参数数量 + 参数数组的格式传入:
1 | int main(int argc, char *argv[]) |
其中 argc 表示参数数量 Argument Count(即命令行上空格隔开字符串的数量),argv Argument Vector 为一个指向这些字符串指针的数组。例如:
1 | % clang -ansi test001.c -o test001.out |
此时 argc = 5,argv = ["clang", "-ansi", "test001.c", "-o", "test001.out"]
这启发我们设计数组作为参数传入函数时,务必同时传入数组长度,否则如果发生越界访问,会极难发现。
在涉及指针运算时,存在内存对齐问题。在内存读取时,是每个 byte 作为独立单位读取的(即我们前面讲到的 byte addressing 导致的),因此数据需要对齐 Alignment。
- 对于整型
int数据(4 byte),要求存储时需要最低位存储在4 byte的整倍数的内存地址上; - 对于短整型
short数据(2 byte),要求存储时需要最低位存储在2 byte的整倍数的内存地址上。
对于指针的运算,C 语言只定义了如下运算:
- 加减整数
- 指针作差
- 指针比较
- 和
NULL比较
其它运算均为不合法运算。
另外,C 语言定义数组越界1位处必为合法地址,但是对这个地址解引用是非法的。这是为了方便检查访问越界,同时不破坏存储的其它数据。
C 语言的内存管理
C 语言程序在运行时的内存分为 4 个区域:栈区 stack,堆区 heap,静态数据区域 static data,代码区 code。这四个区域各有各的用处和特性:

- 栈区 stack:存放连续地址的栈帧(包含函数的返回地址(调用者)、函数参数、函数内部定义的局部变量);函数被调用时入栈,函数终止时弹栈。栈区一般从高地址向低地址生长。
- 堆区 heap:运行时不连续分配的内存区域,由
malloc()calloc()realloc()free()手动管理空间;一般比栈区空间更大(但是也要记得释放空间,防止内存泄漏)。堆区一般从低地址向高地址生长。(不用担心栈区和堆区撞在一起,后续内存分页会解决这个问题) - 静态数据区域 static data:存储全局/静态变量,其中又分为三个区域:
- .rodata 区:是只读的 read-only,存储字符串字面量、(被自动/手动初始化的)const 修饰的全局/静态变量。
- .data 区:存储非零初始化的全局变量/静态变量。
- .bss 区:Block started by symbol,存储未初始化或显式初始化为 0 的全局/静态变量。
- 代码区 code:存储代码,运行时一般只读。
记不住没关系,看一眼下面的程序,你就能理解了。
1 |
|
至此,关于 C 语言的基本知识就介绍得差不多了。对于有 C 语言基础的读者,这部分应该只是复习性质的;对于没有基础的读者,请完全理解以上这一节的内容,然后你的水平就和其他人站在同一起跑线上了。
程序:从代码到执行
在本课程讨论的范围内,程序从代码到执行的过程大致可以分为四步:编译 Compilation - 汇编 Assembly - 链接 Linking - 加载 Loading。

具体的过程在此处不做详细解释,等到我们深入了解完 RISC-V 这门汇编语言,再回来讲每个部分分别做了什么。读者此处只需要大致了解这个过程,以防后续深入某一部分时“只缘身在此山中”。
- 标题: CS110 计算机体系结构 2 梦开始的地方
- 作者: aaaaa
- 创建于 : 2026-07-20 14:00:00
- 更新于 : 2026-07-20 15:38:29
- 链接: https://redefine.ohevan.com/2026/07/20/零基础速通系列/CS110 计算机体系结构/零基础速通:CS110_计算机体系结构_2/
- 版权声明: 版权所有 © aaaaa,禁止转载。