一 概要
mips拥有32个通用寄存器,一个pc寄存器,一个HI和LO寄存器,另外协处理器也有自己的寄存器,如CP0有32个单独的寄存器(不同的厂商可以实现自己独特的寄存器,用MTC0 rt, rd, sel, sel进行区分),浮点协处理单元也有自己独立的寄存器。
二 32个通用寄存器
s0–s8: By convention, subroutines must guarantee that thevalues of
these registers on exit are the same as they were on entry, either by not
using them or by saving them on the stack and restoring them before
exit. This makes them eminently suitable for use as register variables or
for storing any value that must be preserved over a subroutine call.
k0, k1: Reserved for use by an OS trap/interrupt handlers,which will use
them and not restore their original value; they are of little use toanyone
else.
gp: This is used for two distinct purposes. In the kind ofpositionindependent
code (PIC) used by Linux applications, all out-of-module
code and data references go through a table of pointers known as the
GOT (for Global Offset Table). The gp register is maintained to point to
the GOT. See Chapter 16 for details.
In regular non-PIC code (as is used by simpler embedded systems) gp
is sometimes used to point to a link-time-determined location in the midstof your static data. This means that loads and stores to data lying
within 32 KB of either side of the gp value can be performed in a single
instruction using gp as the base register.
Without the global pointer, loading data from a static memory area takes
two instructions: one to load the most significant bits of the 32-bitconstant
address computed by the compiler and loader and one to do the
data load.
To create gp-relative references, a compiler must know at compile time
that a datum will end up linked within a 64-KB range of memory locations.
In practice it can’t know; it can only guess. The usual practice is
to put small global data items (eight bytes and less in size) in thegparea
and to get the linker to complain if it still gets too big.
sp: It takes explicit instructions to raise and lower thestack pointer, so
MIPS code usually adjusts the stack only on subroutine entry and exit;
it is the responsibility of the subroutine being called to do this.spis
normally adjusted, on entry, to the lowest point that the stack will need
to reach at any point in the subroutine.Nowthe compiler can access stack
variables by a constant offset from sp. Once again, see section 11.2.1 for
conventions about stack usage.
fp: Also known as s8, a frame pointer will be used by asubroutine
to keep track of the stack if for any reason the compiler or programmer
was unable or unwilling to compute offsets from the stack pointer.
That might happen, in particular, if the programdoes things that involve
extending the stack by an amount that is determined at run time.
Some languages may do this explicitly; assembly programmers are
always welcome to experiment; and C programs that use the alloca()
library routine will find themselves doing so.
If the stack bottom can’t be computed at compile time, you can’t access
stack variables from sp, so fp is initialized by the function prologue to
a constant position relative to the function’s stack frame. Cunning use
of register conventions means that this behavior is local to the function
and doesn’t affect either the calling code or any nested function calls.
ra: On entry to any subroutine, return address holds theaddress to
which control should be returned—so a subroutine typically ends with
the instruction jr ra. In theory, any register could be used, but some
sophisticated CPUs use optimization (branch prediction) tricks, which
work better if you use a jr ra.
Subroutines that themselves call subroutines must first save ra, usually
on the stack.
详细可以参考:see mips run.pdf
三 CP0寄存器
1. Registers used in memory management.
2. Registers used in exception processing.
3. Registers used in debug.
详细可以参考:4KcProgMan.pdf (MD00016)和 MIPS® Architecture For Programmers Vol. III: MIPS32®/microMIPS32™ Privileged Resource Architecture (MD00090)