User Tools

Site Tools


cpu_abi

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
cpu_abi [2021/08/29 07:08]
someone2639 created Simple ABI page
cpu_abi [2021/10/16 17:31] (current)
someone2639 [Functions With Floating/Decimal Arguments] asm corrections
Line 38: Line 38:
 ==== Functions With More Than Four Arguments ==== ==== 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:+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 a stack frame (the view of the stack from any arbitrary function) ​is as shown:
  
 == General Stack Usage == == General Stack Usage ==
Line 46: Line 46:
 | 0x08 | (RESERVED) Stores a2 | | 0x08 | (RESERVED) Stores a2 |
 | 0x0C | (RESERVED) Stores a3 | | 0x0C | (RESERVED) Stores a3 |
-| 0x10 | Stores the return address for non-leaf functions | +| 0x10 | Fifth 32-bit argument | 
-| 0x14 | Fifth 32-bit argument | +0x14 | Sixth 32-bit argument | 
-0x18 | Sixth 32-bit argument | +0x18 | Seventh 32 bit argument |
-0x1C | Seventh 32 bit argument |+
 | .... | Every subsequent 32-bit argument will be on a multiple of 4 on the stack | | .... | Every subsequent 32-bit argument will be on a multiple of 4 on the stack |
 +| Top of stack | (RESERVED) Stores the return address for non-leaf functions |
  
-NOTE: on most N64 games, too much stack is allocated, so the layout looks more like this:+Let's see how this looks in practice:
  
-== Stack Usage on IDO == +C Function ​     ​Equivalent ASM       
-Stack Offset ​Purpose ​+<code c>myFunc(0, 1, 2, 3, 4, 5, 6, 7, 8);</​code> ​   ​<​code>​ 
-0x00 | (RESERVEDStores a0 +li a0, 0 
-| 0x04 | (RESERVEDStores a1 | +li a1, 1 
-| 0x08 | (RESERVEDStores a2 | +li a2, 2 
-| 0x0C | (RESERVEDStores a3 +li a3, 3 
-0x10 | Unused ​+li t0, 4 
-0x14 | Stores ​the return address ​for non-leaf functions | +sw t0, 0x10(sp
-| 0x18 | Fifth 32-bit argument | +li t0, 5 
-0x1C | Sixth 32-bit argument | +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 
 +</​code> ​    | 
 + 
 +Now the question is where the top of the stack is, and how to avoid it. This is also explained in code: 
 + 
 +^ C Function ​     ^ Equivalent ASM       ^ 
 +<code c>void myFunc(int a, int b, int c, int d, int e, int f, int g, int h) {...</​code> ​   ​<​code>​ 
 +glabel myFunc 
 +    addiu sp, -0x30 
 +    sw ra, 0x2C(sp) 
 +    ... 
 +    lw ra, 0x2C(sp) 
 +    jr ra 
 +    addiu sp, 0x30 
 +</​code> ​    | 
 + 
 +The ''​addiu''​ instruction determines how much gets allocated to the stack, and the return address ​is placed at the top of this region. 
 + 
 +==== Functions With Floating/​Decimal Arguments ==== 
 + 
 +When a function takes floating point arguments, the ABI assumes you're using float registers more often and gives each of them their own purpose so you dont have to use general purpose registers too much. 
 + 
 +^ C Function ​     ^ Equivalent ASM       ^ 
 +<code c> 
 +float three_input_adder(float a, float b, float c) { 
 +    return a + b + c; 
 +
 +void myFunc(void) { 
 +    float x = three_input_adder(1.0f,​ 3.0f, 4.0f); 
 +} 
 +</​code> ​   ​<​code>​ 
 +glabel three_input_adder 
 +    lwc1 f4, 0x10(sp) 
 +    add.s f0, f12, f14 
 +    add.s f0, f0, f4 ; return value gets stored in f0 
 +    jr ra 
 +     nop 
 +glabel myFunc 
 +    addiu sp, -0x18 
 +    sw ra, 0x14(sp) 
 +     
 +    li.s f12, 1.0 ; f12 holds the first argument 
 +    li.s f14, 3.0 ; f14 holds the second argument 
 +    li.s f4,  4.
 +    swc1 f4, 0x10(sp) ; subsequent float arguments go on the stack 
 +    jal three_input_adder 
 +     nop 
 +     
 +    mfc1 t0, f0 ; f0 has the result 
 +     
 +    lw ra, 0x14(sp) 
 +    jr ra 
 +     addiu sp, 0x18 
 +</​code> ​    |
  
cpu_abi.1630220915.txt.gz · Last modified: 2021/08/29 07:08 by someone2639