This commit is contained in:
2026-03-30 16:09:38 +08:00
commit cfc02abdc5
5 changed files with 306 additions and 0 deletions

56
CSAPP/L08 Data.md Normal file
View File

@@ -0,0 +1,56 @@
# L08 Data
多个数据元素放到一起的情况
## 目录
- Arrays 数组
- Structures 结构体
- Floating Point 浮点数
## Arrays 数组
数组分配的基本思想相当简单: 在内存中分配一块儿连续的空间存储元素。
```T array[L]```
- 一个数据类型为T的数组包含L个元素
- 在内存中占用**连续**的```L * sizeof(T)```字节的空间
- 数组名```array```可以被转换为指向数组元素0的指针 (```Type T *```)
- - 是C语言特殊的原因之一[^Why-Is-C-Special-Array-Pointer]
[^Why-Is-C-Special-Array-Pointer]: C 语言中的数组解引用运算符 [ ] 是用指针定义的```x[y]```的意思是:从指针```x```开始,向前移动```y```个元素,然后取下那里的所有元素。使用指针运算语法, ```x[y]``` 也可以写成 ```*(x+y)``` 。有一个例外情况: 计算```sizeof(array)```时,返回一个指针的占用字节数没卵用。因此,在这里,数组名```array```不会被转换为指针,而是返回整个数组占用的字节数。
### Array Access in C C语言中的数组访问
前面的章节已经提到了(A, B, x)这样子的寄存器寻址表示方式。它简直就是为数组访问而生的 -- 看看下面的代码:
```c
typedef int int_arr[5];
int get_num(int_arr arr, int index) {
return arr[index];
}
```
```asm
get_num: # 函数参数: arr -> %rdi, index -> %esi
movslq %esi, %rsi # 将index转换为64位
movl (%rdi,%rsi,4), %eax # 从 (%rdi) + 4 * %rsi 加载元素到eax
ret
```
```(%rdi, %rsi, 4)``` 是一个寄存器寻址模式。参考注释,可以发现它就是指向了```arr[index]```的地址。
很显然Intel格式的汇编语句也会有这种常见操作。
```asm
get_num: # 这是Debug配置下的编译结果因此略显冗长
movsxd rax,dword ptr [index] # 将index转换为64位
mov rcx,qword ptr [arr] # 将arr的地址加载到rcx
mov eax,dword ptr [rcx+rax*4] # 从 (rcx) + 4 * rax 加载元素到eax
ret
```
### Multidimensional Arrays 多维数组