Files
2025-09-25 04:04:35 +08:00

69 lines
2.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
### 函数的调用约定有哪些,区别是什么
**1. `cdecl` (C Declaration)**
这是 C 语言的默认调用约定,也是最常见的
- **参数传递**:从**右到左**依次推入栈中
- **栈清理**:由**调用方(caller)**负责在函数返回后清理栈
- **寄存器**`eax`, `ecx`, `edx` 是调用方保存的(caller-saved)寄存器。这意味着被调用函数可以自由使用这些寄存器,如果调用方需要保存它们,需要在调用前自己推入栈中
**优点**:支持可变参数函数,例如 `printf`
**缺点**:每次函数调用后都需要调用方执行额外的栈清理指令,会增加代码大小
**2. `stdcall` (Standard Call)**
这是 Windows API 的默认调用约定
- **参数传递**:从**右到左**依次推入栈中
- **栈清理**:由**被调用方(callee)**负责清理栈
- **寄存器**:与 `cdecl` 类似
**优点**:代码更精简。由于被调用方知道参数数量,只需一条指令即可清理栈
**缺点**:不支持可变参数函数,因为被调用方需要知道参数数量才能正确清理栈
**3. `fastcall`**
这是一个为了提高性能而设计的调用约定
- **参数传递**:前两个(或更多,具体取决于编译器和架构)参数通过**寄存器**传递,而不是通过栈。其余参数从右到左推入栈中
- **栈清理**:由**被调用方**清理栈
- **寄存器**:使用 `ecx``edx`(在 32 位 Windows 上)或 `rcx``rdx`(在 64 位 Windows 上)来传递前两个参数
**优点**:通过减少内存访问(栈操作)来提高函数调用速度
**缺点**:不支持可变参数函数
**4. `thiscall`**
这是 C++ 中非静态成员函数的默认调用约定
- **参数传递**:与 `cdecl``stdcall` 类似,但隐藏的 `this` 指针(指向对象实例)通过**寄存器**传递
- **栈清理**:由**被调用方**清理栈
**优点**:优化了 C++ 成员函数的调用
**缺点**:只能用于 C++ 成员函数
**5. `pascal` (Pascal Language)**
在老旧的 Windows 16 位编程中很常见,现在很少使用
- **参数传递**:从**左到右**推入栈中
- **栈清理**:由**被调用方**清理栈
**不同平台下的调用约定**
- **Windows (x86)**
- `cdecl`C/C++ 默认
- `stdcall`Windows API 默认
- `fastcall`:用于性能优化
- `thiscall`C++ 成员函数
- **Windows (x64)**
- `__fastcall`:这是 64 位 Windows 的唯一调用约定。前四个整数或指针参数通过 `rcx`, `rdx`, `r8`, `r9` 寄存器传递。其余参数从右到左推入栈中
- **Linux (x86)**
- `cdecl`:默认
- **Linux (x64)**
- 前六个整数或指针参数通过 `rdi`, `rsi`, `rdx`, `rcx`, `r8`, `r9` 寄存器传递。其余参数从右到左推入栈中