The MIPS assembler was originally written by Christian Pirker.
Currently the assembler and disassembler covers most of the MIPS32 architecture and doesn’t support FP instructions.
The register names
$a3 are not available to avoid
shadowing hex numbers. Use register numbers
Nothing distinguishes registers from immediate values. Use explicit
opcode names with the
i suffix for instructions with immediate
addiu, in place of
Where the architecture manual specifies several formats for the
instruction (e.g., for
jalr,),use the one with more arguments
(i.e. two for
jalr,). When in doubt, see
arch/mips/testasm.fs for an example of correct use.
Branches and jumps in the MIPS architecture have a delay slot. You
have to fill it manually (the simplest way is to use
assembler does not do it for you (unlike
repeat, need a delay slot.
then, just specify branch targets, they
are not affected. For branches the argument specifying the target is
a relative address. Add the address of the delay slot to get the
Note that you must not put branches nor jumps (nor control-flow
instructions) into the delay slot. Also it is a bad idea to put
pseudo-ops such as
li, into a delay slot, as these may expand
to several instructions. The MIPS I architecture also had load delay
slots, and newer MIPSes still have restrictions on using
mflo,. Be careful to satisfy these restrictions, the
assembler does not do it for you.
Some example of instructions are:
$ra 12 $sp sw, \ sw ra,12(sp) $4 8 $s0 lw, \ lw a0,8(s0) $v0 $0 lui, \ lui v0,0x0 $s0 $s4 $12 addiu, \ addiu s0,s4,0x12 $s0 $s4 $4 addu, \ addu s0,s4,$a0 $ra $t9 jalr, \ jalr t9
You can specify the conditions for
if, etc. by taking a
conditional branch and leaving away the
b at the start and the
, at the end. E.g.,
4 5 eq if, ... \ do something if $4 equals $5 then,
The calling conventions for 32-bit MIPS machines is to pass the first
4 arguments in registers
$7, and to use
$v1 for return values. In addition to these
registers, it is ok to clobber registers
saving and restoring them.
If you use
jalr, to call into dynamic library routines, you
must first load the called function’s address into
is used by position-indirect code to do relative memory accesses.
Here is an example of a MIPS32
abi-code my+ ( n1 n2 -- n3 ) \ SP passed in $4, returned in $v0 $t0 4 $4 lw, \ load n1, n2 from stack $t1 0 $4 lw, $t0 $t0 $t1 addu, \ add n1+n2, result in $t0 $t0 4 $4 sw, \ store result (overwriting n1) $ra jr, \ return to caller $v0 $4 4 addiu, \ (delay slot) return uptated SP in $v0 end-code