57 lines
2.1 KiB
Markdown
57 lines
2.1 KiB
Markdown
# 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 多维数组
|
||
|