60 lines
2.4 KiB
Markdown
60 lines
2.4 KiB
Markdown
# Calling Convention — Output Explanation
|
|
|
|
This document explains the output of the calling convention algorithm
|
|
implemented in `calling-convention.ipynb`, tested across 3 scenarios.
|
|
|
|
---
|
|
|
|
## TEST 1: A single 1-byte argument
|
|
|
|
**Function signature:** `result = func(x)` where `x` is 8 bits (1 byte)
|
|
|
|
**Output:**
|
|
```
|
|
===== TEST 1: a 1 byte argument =====
|
|
=== State after do_function_call ===
|
|
Registers used: ['RA']
|
|
Stack: [{'type': 'caller_saved', 'reg': 'R0', 'value': 0}, {'type': 'caller_saved', 'reg': 'R1', 'value': 0}, {'type': 'caller_saved', 'reg': 'R2', 'value': 0}, {'type': 'caller_saved', 'reg': 'R3', 'value': 0}]
|
|
RS points to: 4
|
|
=== State after undo_function_call ===
|
|
Clean stack: []
|
|
RS: 0
|
|
Collected result: {'result': {'type': 'result', 'value': 42}}
|
|
```
|
|
|
|
**Explanation:**
|
|
|
|
Since there is only one argument and it fits in a single register, it is
|
|
placed directly in `RA` (the first available argument register).
|
|
Before the call, the 4 caller-saved registers (R0-R3) are pushed onto the
|
|
stack to preserve their values. `RS` points to position 4, reflecting those
|
|
4 entries. After `undo_function_call`, the stack is empty, `RS` returns to 0,
|
|
and the result value `42` is successfully collected from `RA`.
|
|
|
|
---
|
|
|
|
## TEST 2: 8 arguments, some overflow to the stack
|
|
|
|
**Function signature:** `result = func(a, b, c, d, e, f, g, h)`
|
|
|
|
**Output**
|
|
```
|
|
===== TEST 2: 8 arguments, some on the stack =====
|
|
=== State after do_function_call ===
|
|
Registers used: ['RA', 'RB', 'RC', 'RD', 'R8', 'R9']
|
|
Stack: [{'type': 'caller_saved', 'reg': 'R0', 'value': 0}, {'type': 'caller_saved', 'reg': 'R1', 'value': 0}, {'type': 'caller_saved', 'reg': 'R2', 'value': 0}, {'type': 'caller_saved', 'reg': 'R3', 'value': 0}, {'type': 'param', 'name': 'g', 'size': 64, 'value': 0}, {'type': 'param', 'name': 'h', 'size': 64, 'value': 0}]
|
|
RS points to: 6
|
|
=== State after undo_function_call ===
|
|
Clean stack: []
|
|
RS: 0
|
|
Collected result: {'result': {'type': 'result', 'value': 99}}
|
|
```
|
|
|
|
**Explanation:**
|
|
Spider provides 6 registers for passing arguments: RA, RB, RC, RD, R8, R9.
|
|
The first 6 arguments (a through f) fill all available registers.
|
|
Arguments `g` and `h`, which are 64-bit values, have no registers left and
|
|
are pushed onto the stack instead. `RS` points to 6, reflecting the 4
|
|
caller-saved entries plus 2 stack parameters. After `undo_function_call`,
|
|
all stack entries are cleaned and the result `99` is collected from `RA`.
|