s means saved, referring to their function in the ABI.
saved (or in more common naming, non-volatile) means that if a subroutine/function uses that register, it must restore it to its old value before exiting.
- On MIPS though, there's also the
tregisters (temporary, or volatile in more common naming)
Subroutines can do whatever the fuck they want with them, compilers will assume volatile registers are thrashed by function calls* and not rely on their values not changing
*This is not true depending on compiler optimizations
Then you've got :
k or kernel registers- Reserved for the kernel, please don't touch this unless you know what you're doing
a or argument registers- Your parameters go in here on function calls. For example if you have a function with the signature myFunc (int a, int b), a will go in $a0 and b will go in $a1. In more modern architectures, the "argument registers" are usually a sub-section of the volatiles.
$at: This is, as its name implies a temporary register for the assembler.
There's some assembler macros like
lw $dest, 32_BIT_ADDRESS.
load32 $v0, 0x1F801814to get GPUSTAT.
This is not a valid instruction, it's a macro that your assembler might compile to ...
lui $at, 0x1F80 lw $v0, 0x1814($at)
...if it supports macros like this. It's a bullshit name and it's volatile.
$sp: Stack pointer. MIPS doesn't have a traditional stack. It's stack is essentially having a conventional stack pointer register and using sp-relative loads/stores.
$ra: The return address will be stored here when calling a function, so you can return with
$v0, $v1: First and second return values respectively
$gp: A global pointer that points to a global memory area so it's easily accessible.
For example on x86-64, the stack pointer (rsp) is considered saved on every ABI.
Errr rsp is a bad example, let's use rbp instead...
If I want to do :
my_asm_func: add rbp, 69 ret
I'll fuck up any HLL code that jumps to this function, because I'm corrupting a register that the ABI says is saved/non-volatile.
On the other hand:
push rbp ; save rbp in stack <do things with rbp here> pop rbp ; restore rbp ret
is perfectly valid. I am corrupting a non-volatile register but restoring its value before returning