I wrote these notes on July 6th, 1998 and as of March 2007
no longer have any idea what I used them for.
Ricardo Nabinger Sanchez has helpfully pointed out what is almost
certainly an error, in that identical subu
instructions are
used to allocate and free the stack frame.
I do not know which one should be corrected, and how.
-- John Chew <poslfit@gmail.com>
start | end | description |
---|---|---|
0000 0000 | 003F FFFF | Reserved |
0040 0000 | ____ ____ | Code (.text) |
____ ____ | 0FFF FFFF | Shared libraries |
1000 0000 | ____ ____ | Read-only data (.rdata) |
____ ____ | ____ ____ | Data (.data) |
____ ____ | $gp | Short-offset data (.sdata) |
$gp | ____ ____ | Short-offset uninitialised data (.sbss) |
____ ____ | ____ ____ | Uninitialised data (.bss) |
____ ____ | ____ ____ | Heap (expanded by sbrk and break) |
____ ____ | $sp | Protected |
$sp | 7FFF EFFF | Stack |
7FFF F000 | 7FFF FFFF | Not accessible |
8000 0000 | FFFF FFFF | Kernel |
/usr/include/regdefs.h
.
Register Name | Software Name | Description |
---|---|---|
$0 | Always set to zero | |
$at | Assembler temporary register | |
$2, $3 | v0, v1 | Expression evaluation, integer function results, static link for nested procedure calls |
$4..$7 | a0..a3 | First four volatile int arguments |
$8..$15 | t0..t7 | Not preserved across procedure calls |
$16..$23 | s0..s7 | Preserved across procedure calls |
$24, $25 | t8, t9 | Not preserved across procedure calls |
$kt0, $kt1 | k0, k1 | Kernel use only |
$28 or $gp | gp | Global pointer |
$29 or $sp | sp | Stack pointer |
$30 or $fp | fp | Frame pointer (if used) |
$31 | ra | Return address |
$4
through $7
and the first two
floating point arguments must be placed in registers f12
and f14
.
Return values go in $2
and
$f0
.
To call a procedure, use the jal
instruction.
jal procedure_name
.ent
directive and entry label.
.ent procedure_name procedure_name:If your procedure requires stack storage, either because it calls other procedures, or because it needs to put local variables on the stack, allocate the required storage. You should not modify the stack pointer again, except to restore it on return.
subu $sp, framesizeRegardless of whether or not you use stack storage, include the following pseudo-op. It tells the debugger how big your stack frame is.
.frame framereg, framesize, returnregFramereg is usually
$sp
, returnreg is usually
$31
. If you need to save integer registers, e.g. $16, $17 and $31, do so as follows.
.mask bitmask, frameoffset sw $31, framesize+frameoffset-0($sp) sw $17, framesize+frameoffset-4($sp) sw $16, framesize+frameoffset-8($sp)If you need to save floating point registers, use
s.s
or s.d
instead of sw
, and .fmask
instead of .mask
. Allow four bytes for singles, eight bytes
for doubles.Include your procedure body (if any) here.
To restore registers, use lw
, l.s
and
l.d
.
lw $16, framesize+frameoffset-8($sp) lw $17, framesize+frameoffset-4($sp) lw $31, framesize+frameoffset-0($sp)Remove the stack frame.
subu $sp, framesizeReturn.
j $31End the procedure definition.
.end procedure_name