User Tools

Site Tools


cpu_abi

This is an old revision of the document!


Nintendo 64 ABI and Calling Convention

The Nintendo 64 uses a MIPS architecture NEC VR4300i, and applications created for the system are all compiled with C or C++. For the assembly developer looking to hack games that use C, knowing the calling convention used is one of the most important things you can know.

The MIPS o32 ABI determines 3 things: The register names and uses, the allocation of the stack, and how to effectively call functions using those.

Argument Passing

Normal/Pointer Arguments

Four registers are used for passing arguments to a function: a0, a1, a2, and a3. These arguments can hold any value up to 32 bits each, which includes pointer addresses.

C Function Equivalent ASM
myFunc(0, 1, 0x12345678, &myPointer);
li a0, 0
li a1, 1
li a2, 0x12345678
la a3, myPointer ; Loads an address value
jal myFunc
; make sure 'li' and 'la' instructions
; don't fall into a delay slot,
; otherwise only half of the value
; will load.
nop

If a function returns a value, it will be stored in v0.

C Function Equivalent ASM
myFunc(myReturningFunc());
jal myReturningFunc
nop
move a0, v0 ; move v0 to a0
jal myFunc
nop

Functions With More Than Four Arguments

The ABI specifies four argument registers, so the natural thing to wonder is where a to put a fifth argument, sixth argument, and so on. The answer is to put them on the Stack. The general layout of the stack is as shown:

General Stack Usage
Stack Offset Purpose
0x00 (RESERVED) Stores a0
0x04 (RESERVED) Stores a1
0x08 (RESERVED) Stores a2
0x0C (RESERVED) Stores a3
0x10 Fifth 32-bit argument
0x14 Sixth 32-bit argument
0x18 Seventh 32 bit argument
…. Every subsequent 32-bit argument will be on a multiple of 4 on the stack
-0x04 (RESERVED) Stores the return address for non-leaf functions

(-0x04 essentially means the return address is at the top of whatever region was allocated. More on that later.)

Let's see how this looks in practice:

C Function Equivalent ASM
myFunc(0, 1, 2, 3, 4, 5, 6, 7, 8));
li a0, 0
li a1, 1
li a2, 2
li a3, 3
li t0, 4
sw t0, 0x10(sp)
li t0, 5
sw t0, 0x14(sp)
li t0, 6
sw t0, 0x18(sp)
li t0, 7
sw t0, 0x1C(sp)
li t0, 8
sw t0, 0x20(sp)
jal myFunc
nop
cpu_abi.1630222334.txt.gz · Last modified: 2021/08/29 07:32 by someone2639