78 lines
4.4 KiB
Markdown
78 lines
4.4 KiB
Markdown
|
# Calling Conventions
|
|||
|
|
|||
|
## Cheatsheet
|
|||
|
|
|||
|
| Platform | Return Value | Parameter Registers | Additional Parameters | Stack Alignment | Scratch Registers | Preserved Registers | Call List |
|
|||
|
| -------------------------------------------------------------------- | ------------ | -------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------- | ----------------------------------------- | ------------------------------------------- | --------- |
|
|||
|
| System V i386 | eax, edx | none | stack (right to left)[1](https://wiki.osdev.org/Calling_Conventions#Note1) | | eax, ecx, edx | ebx, esi, edi, ebp, esp | ebp |
|
|||
|
| System V X86_64[2](https://wiki.osdev.org/Calling_Conventions#Note2) | rax, rdx | rdi, rsi, rdx, rcx, r8, r9 | stack (right to left)[1](https://wiki.osdev.org/Calling_Conventions#Note1) | 16-byte at call[3](https://wiki.osdev.org/Calling_Conventions#Note3) | rax, rdi, rsi, rdx, rcx, r8, r9, r10, r11 | rbx, rsp, rbp, r12, r13, r14, r15 | rbp |
|
|||
|
| Microsoft x64 | rax | rcx, rdx, r8, r9 | stack (right to left)[1](https://wiki.osdev.org/Calling_Conventions#Note1) | 16-byte at call[3](https://wiki.osdev.org/Calling_Conventions#Note3) | rax, rcx, rdx, r8, r9, r10, r11 | rbx, rdi, rsi, rsp, rbp, r12, r13, r14, r15 | rbp |
|
|||
|
| ARM (32-bit) | r0, r1 | r0, r1, r2, r3 | stack | 8 byte[4](https://wiki.osdev.org/Calling_Conventions#Note4) | r0, r1, r2, r3, r12 | r4, r5, r6, r7, r8, r9, r10, r11, r13, r14 | |
|
|||
|
|
|||
|
## System V i386
|
|||
|
|
|||
|
- Parametres are pushed to stack from right to left
|
|||
|
- Caller cleans the stack
|
|||
|
- Callee is free to modify parametres
|
|||
|
- Caller must not assume they stayed the same!
|
|||
|
- Scratch registers are `EAX`, `ECX` and `EDX`
|
|||
|
- Caller must preserve if needed
|
|||
|
- Function preserves `EBX`, `ESI`, `EDI` and `EBP`
|
|||
|
- Return value in `EAX`
|
|||
|
- If 64bit value: higher 32bits in `EDX`
|
|||
|
- Functions push `ebp` such that the caller-return-eip is 4 bytes above it, and set `ebp` to the address of the saved ebp.
|
|||
|
- Allows iterating through the existing stack frames.
|
|||
|
- Can be eliminated by specifying the -fomit-frame-pointer GCC option.
|
|||
|
|
|||
|
## CDECL
|
|||
|
|
|||
|
**Caller's responsibilities**
|
|||
|
- Push parameters in reverse order (last parameter pushed first)
|
|||
|
- Perform the call
|
|||
|
- Pop the parameters, use them, or simply increment `ESP` to remove them (stack clearing)
|
|||
|
- The return value is stored in `EAX`
|
|||
|
|
|||
|
**Callee's responsibilities (callee is the routine being called)**
|
|||
|
- Store caller's `EBP` on the stack
|
|||
|
- Save current `ESP` in `EBP`
|
|||
|
- Code, storing local data on the stack
|
|||
|
- For a fast exit load the old `ESP` from `EBP`, else pop local data elements
|
|||
|
- Pop the old `EBP` and return – store return value in `EAX`
|
|||
|
|
|||
|
**It looks like this in assembly (NASM)**
|
|||
|
``` nasm
|
|||
|
SECTION .text
|
|||
|
|
|||
|
caller:
|
|||
|
|
|||
|
; ...
|
|||
|
|
|||
|
; Caller responsibilities:
|
|||
|
PUSH 3 ; push the parameters in reverse order
|
|||
|
PUSH 2
|
|||
|
CALL callee ; perform the call
|
|||
|
ADD ESP, 8 ; stack cleaning (remove the 2 words)
|
|||
|
|
|||
|
; ... Use the return value in EAX ...
|
|||
|
|
|||
|
|
|||
|
callee:
|
|||
|
|
|||
|
; Callee responsibilities:
|
|||
|
PUSH EBP ; store caller's EBP
|
|||
|
MOV EBP, ESP ; save current stack pointer in EBP
|
|||
|
|
|||
|
; ... Code, store return value in EAX ...
|
|||
|
|
|||
|
; Callee responsibilities:
|
|||
|
MOV ESP, EBP ; remove an unknown number of local data elements
|
|||
|
POP EBP ; restore caller's EBP
|
|||
|
RET ; return
|
|||
|
```
|
|||
|
|
|||
|
## Sources
|
|||
|
- [https://wiki.osdev.org/Stack](https://wiki.osdev.org/Stack)
|
|||
|
- [https://wiki.osdev.org/Calling_Conventions](https://wiki.osdev.org/Calling_Conventions)
|
|||
|
- [https://wiki.osdev.org/System_V_ABI](https://wiki.osdev.org/System_V_ABI)
|
|||
|
|
|||
|
**TODO:** Check if SysV ABI and CDECL are really the same thing?
|