Skip to content

Commit

Permalink
[PUBLISHER] Merge #93
Browse files Browse the repository at this point in the history
  • Loading branch information
HeZeBang authored Sep 26, 2024
1 parent 401d2a8 commit 411506c
Showing 1 changed file with 2 additions and 44 deletions.
46 changes: 2 additions & 44 deletions docs/ShanghaiTech/Compilers/Compilers.Lec.4.md
Original file line number Diff line number Diff line change
Expand Up @@ -394,9 +394,7 @@ let p4 (n : int) : prog =
与 p3 不同,这里用的是递归的方式,也就是说,函数的“循环”操作不再依赖 `jmp`,而是用 `call` (虽然本质上都是改变 rip,但是调用函数需要有栈的操作)
虽然这里的栈的操作看起来是多余的,但是向我们展示了 `call` 的用法

### Programming in X86lite

#### 关于存储
### Programming in X86lite - Storage

基本的 C 内存模型包含三个部分,地址从高到低分别为

Expand All @@ -410,44 +408,4 @@ let p4 (n : int) : prog =
- Code & data (and text)
- 包括编译后的代码,字符串常量等

我们可能需要存储全局变量、函数参数、(原先或者编译器定义的)局部变量。我们可以存储到快速但空间小的 Register 或者慢速但空间大的 Memory(或者 Cache)。在 X86 的实践中, Reg 有限,而 Mem 被划分为了很多带有堆栈的小区域。

#### 函数调用

> 下面以 X86-64 SYSTEM V AMD 64 ABI 为例
根据调用的主从关系分为 Caller / Callee,例如 `a` 调用了 `b` ,则 `b.caller` 就是 `a`

而寄存器也分为

- Callee Save,例如 `rbp`, `rbx`, `r12-15` 等 - 被调用者保存,被调用的函数 `b` 有责任在被调用时先保存一份寄存器,然后在返回时恢复。
- Caller Save,调用者保存,如果 `a` 想在调用 `b` 之后继续使用这些寄存器的话,那 `a` 有责任在调用 `b` 前保存一份在之后恢复,`b` 可以自由使用而没有限制。

定义栈分配参数的清理协议:

- 调用者负责清理。
- 被调用者负责清理(这使得支持可变数量参数变得更困难)。

**参数的分配**

- 1~6:按顺序存放在 `rdi`, `rsi`, `rdx`, `rcx`, `r8`, `r9`
- 其他:入栈(right-to-left),例如 n-th arg 的地址为:`(((n-7)+2)*8)(%rbp)`

**返回值**

- 存储在 `rax`

**128-byte 红线** (128 byte "red zone"): 栈上的一个特定区域,通常大小为 128 字节,位于栈顶。

- 可以被被调用函数用来存储临时数据,而无需调整栈指针,减少指针修改
- 在许多 C 编译器中被使用,编译器可以将那些只在函数内部使用的局部变量放入红区,从而节省栈空间,提高函数调用的效率。并不是必需的 x86-64 特性。
- 可以优化

**32-bit cdecl 调用约定**

- 在许多基于 C 的操作系统中仍然被广泛使用
- 返回值:通过 `EAX` 寄存器返回的(有一些不统一,例如一些编译器使用寄存器 EAX 和 EDX 来返回小的值,以及 64 位可以在一个寄存器中打包多个返回值)
- 传参:所有参数都是按照从右到左的顺序通过栈传递。这意味着最后一个参数先入栈,第一个参数最后入栈。
- 寄存器:`EAX`, `ECX`, `EDX` 都是 Caller Save,其他为 Callee Save

下面的示例见 [Slides.4.14](https://www.seas.upenn.edu/~cis3410/current/_static/lectures/lec04.pdf#page=14)
我们可能需要存储全局变量、函数参数、(原先或者编译器定义的)局部变量。我们可以存储到快速但空间小的 Register 或者慢速但空间大的 Memory(或者 Cache)。在 X86 的实践中, Reg 有限,而 Mem 被划分为了很多带有堆栈的小区域。

0 comments on commit 411506c

Please sign in to comment.