MIPS Complete Documentation
Instructions
abs $reg, $reg
ABSolute value : Set $t1 to absolute value of $t2 (algorithm from Hacker's Delight)
abs.d $freg, $freg
Floating-point absolute value (double) : Sets $f2 to the absolute value of $f4 (double-precision). Both register numbers must be even. Works by clearing the sign bit of the high word.
abs.s $freg, $freg
Floating-point absolute value (single) : Sets $f0 to the absolute value of $f1 (single-precision). Works by clearing the sign bit. Does not raise exceptions for NaN or infinity.
add $reg, $reg, [$reg / imm]
Add (signed, overflow trap) : Sets $t1 = $t2 + $t3 using signed 32-bit arithmetic. Raises an overflow exception if the true result does not fit in 32 bits. Use 'addu' when overflow should be silently ignored.
ADDition : set $t1 to ($t2 plus 16-bit immediate)
ADDition : set $t1 to ($t2 plus 32-bit immediate)
add.d $freg, $freg, $freg
Floating-point add (double) : Sets $f2 = $f4 + $f6 using IEEE 754 double-precision (64-bit) arithmetic. Double-precision values have about 15 significant decimal digits. All three register numbers must be even, as each double occupies a pair of FP registers.
add.s $freg, $freg, $freg
Floating-point add (single) : Sets $f0 = $f1 + $f3 using IEEE 754 single-precision (32-bit) arithmetic. Single-precision values have about 7 significant decimal digits. The result is stored in one FP register.
addi $reg, $reg, imm
Add immediate (signed, overflow trap) : Sets $t1 = $t2 + immediate, where the immediate is a signed 16-bit constant (-32768 to 32767) sign-extended to 32 bits. Raises an overflow exception if the result overflows. Use 'addiu' to suppress the overflow check.
ADDition Immediate : set $t1 to ($t2 plus 32-bit immediate)
addiu $reg, $reg, imm
Add immediate unsigned (no overflow trap) : Sets $t1 = $t2 + immediate. The immediate is a signed 16-bit value sign-extended to 32 bits; no overflow exception is raised. Despite the name the immediate is sign-extended, not zero-extended. The most common add-immediate instruction.
ADDition Immediate Unsigned: set $t1 to ($t2 plus 32-bit immediate), no overflow
addu $reg, $reg, [$reg / imm]
Add unsigned (no overflow trap) : Sets $t1 = $t2 + $t3. No exception is raised on overflow; the result wraps modulo 2^32. Despite the name, this works fine with signed values too when you don't need overflow detection.
ADDition Unsigned : set $t1 to ($t2 plus 32-bit immediate), no overflow
and $reg, [$reg / imm], [$reg / imm]
Bitwise AND : Sets $t1 = $t2 & $t3. Each bit of $t1 is 1 only if the corresponding bit is 1 in both $t2 and $t3. Commonly used to mask (isolate) specific bits in a value.
AND : set $t1 to ($t2 bitwise-AND 16-bit unsigned immediate)
AND : set $t1 to ($t1 bitwise-AND 16-bit unsigned immediate)
andi $reg, [$reg / imm], imm
Bitwise AND immediate : Sets $t1 = $t2 & immediate. The 16-bit immediate is zero-extended (upper 16 bits become 0, not sign-extended) before the AND. Commonly used to mask off the lower 16 bits of a register or to test individual bits.
AND Immediate : set $t1 to ($t2 bitwise-AND 32-bit immediate)
AND Immediate : set $t1 to ($t1 bitwise-AND 16-bit unsigned immediate)
AND Immediate : set $t1 to ($t1 bitwise-AND 32-bit immediate)
b id
Branch : Branch to statement at label unconditionally
bc1f [id / imm], id
Branch if FP condition flag 0 is false : Branches to 'label' if Coprocessor 1 condition flag 0 is false (0). Use after a FP compare instruction when you want to branch on the condition NOT being met. Note: mnemonic is BC1F, not BCLF.
Branch if specified FP condition flag is false : Branches to 'label' if the FP condition flag specified by the immediate operand is false (0). Allows branching on the unset result of any of the 8 FP condition flags.
bc1t [id / imm], id
Branch if FP condition flag 0 is true : Branches to 'label' if Coprocessor 1 condition flag 0 is true (1). Set by a preceding FP compare instruction such as 'c.eq.s' or 'c.lt.d'. Note: mnemonic is BC1T (branch Coprocessor-1 True), not BCLT.
Branch if specified FP condition flag is true : Branches to 'label' if the FP condition flag specified by the immediate operand is true (1). Allows branching on any of the 8 condition flags set by FP compare instructions.
beq $reg, [$reg / imm], id
Branch on equal : Branches to 'label' if $t1 == $t2. Uses a PC-relative 16-bit signed offset (multiplied by 4) so the target must be within ±32 KB. Commonly the first half of an if/else test.
Branch if EQual : Branch to statement at label if $t1 is equal to 16-bit immediate
Branch if EQual : Branch to statement at label if $t1 is equal to 32-bit immediate
beqz $reg, id
Branch if EQual Zero : Branch to statement at label if $t1 is equal to zero
bge $reg, [$reg / imm], id
Branch if Greater or Equal : Branch to statement at label if $t1 is greater or equal to $t2
Branch if Greater or Equal : Branch to statement at label if $t1 is greater or equal to 16-bit immediate
Branch if Greater or Equal : Branch to statement at label if $t1 is greater or equal to 32-bit immediate
bgeu $reg, [$reg / imm], id
Branch if Greater or Equal Unsigned : Branch to statement at label if $t1 is greater or equal to $t2 (unsigned compare)
Branch if Greater or Equal Unsigned : Branch to statement at label if $t1 is greater or equal to 16-bit immediate (unsigned compare)
Branch if Greater or Equal Unsigned : Branch to statement at label if $t1 is greater or equal to 32-bit immediate (unsigned compare)
bgez $reg, id
Branch on greater than or equal to zero : Branches to 'label' if $t1 >= 0 (signed comparison). Uses a PC-relative 16-bit signed offset. Commonly used to test the sign bit.
bgezal $reg, id
Branch on greater than or equal to zero and link : Branches to 'label' if $t1 >= 0 (signed), and saves the return address (PC + 4) in $ra. Combines a conditional branch with a function call. Use 'jr $ra' to return.
bgt $reg, [$reg / imm], id
Branch if Greater Than : Branch to statement at label if $t1 is greater than $t2
Branch if Greater Than : Branch to statement at label if $t1 is greater than 16-bit immediate
Branch if Greater Than : Branch to statement at label if $t1 is greater than 32-bit immediate
bgtu $reg, [$reg / imm], id
Branch if Greater Than Unsigned: Branch to statement at label if $t1 is greater than $t2 (unsigned compare)
Branch if Greater Than Unsigned: Branch to statement at label if $t1 is greater than 16-bit immediate (unsigned compare)
bgtz $reg, id
Branch on greater than zero : Branches to 'label' if $t1 > 0 (signed comparison). Uses a PC-relative 16-bit signed offset.
ble $reg, [$reg / imm], id
Branch if Less or Equal : Branch to statement at label if $t1 is less than or equal to $t2
Branch if Less or Equal : Branch to statement at label if $t1 is less than or equal to 16-bit immediate
Branch if Less or Equal : Branch to statement at label if $t1 is less than or equal to 32-bit immediate
bleu $reg, [$reg / imm], id
Branch if Less or Equal Unsigned : Branch to statement at label if $t1 is less than or equal to $t2 (unsigned compare)
Branch if Less or Equal Unsigned : Branch to statement at label if $t1 is less than or equal to 16-bit immediate (unsigned compare)
Branch if Less or Equal Unsigned : Branch to statement at label if $t1 is less than or equal to 32-bit immediate (unsigned compare)
blez $reg, id
Branch on less than or equal to zero : Branches to 'label' if $t1 <= 0 (signed comparison). Uses a PC-relative 16-bit signed offset.
blt $reg, [$reg / imm], id
Branch if Less Than : Branch to statement at label if $t1 is less than $t2
Branch if Less Than : Branch to statement at label if $t1 is less than 16-bit immediate
Branch if Less Than : Branch to statement at label if $t1 is less than 32-bit immediate
bltu $reg, [$reg / imm], id
Branch if Less Than Unsigned : Branch to statement at label if $t1 is less than $t2
Branch if Less Than Unsigned : Branch to statement at label if $t1 is less than 16-bit immediate
Branch if Less Than Unsigned : Branch to statement at label if $t1 is less than 32-bit immediate
bltz $reg, id
Branch on less than zero : Branches to 'label' if $t1 < 0 (signed comparison). Uses a PC-relative 16-bit signed offset.
bltzal $reg, id
Branch on less than zero and link : Branches to 'label' if $t1 < 0 (signed), and saves the return address (PC + 4) in $ra. Combines a conditional branch with a function call. Use 'jr $ra' to return.
bne $reg, [$reg / imm], id
Branch on not equal : Branches to 'label' if $t1 != $t2. Opposite of 'beq'. Uses a PC-relative 16-bit signed offset. Commonly used to branch out of loops or skip else blocks.
Branch if Not Equal : Branch to statement at label if $t1 is not equal to 16-bit immediate
Branch if Not Equal : Branch to statement at label if $t1 is not equal to 32-bit immediate
bnez $reg, id
Branch if Not Equal Zero : Branch to statement at label if $t1 is not equal to zero
break imm
Breakpoint with code : Raises a breakpoint exception with the given numeric code. Halts execution in this simulator. Useful for embedding debug checkpoints in code, similar to a hardware breakpoint.
Breakpoint : Raises a breakpoint exception (no code). Halts execution in this simulator. Used as an unconditional software breakpoint — the zero-code variant of 'break N'.
c.eq.d [$freg / imm], $freg, $freg
FP compare equal (double) : Sets FP condition flag 0 to true if $f2 == $f4 (double-precision), false otherwise. Both register numbers must be even. Use 'bc1t'/'bc1f' to branch on the result.
FP compare equal (double, flagged) : Sets FP condition flag N (specified by the first operand) to true if $f2 == $f4 (double-precision), false otherwise. Both register numbers must be even.
c.eq.s [$freg / imm], $freg, $freg
FP compare equal (single) : Sets FP condition flag 0 to true if $f0 == $f1 (single-precision), false otherwise. Use 'bc1t' to branch when equal, or 'bc1f' to branch when not equal.
FP compare equal (single, flagged) : Sets FP condition flag N (specified by the first operand) to true if $f0 == $f1 (single-precision), false otherwise. Allows multiple simultaneous FP comparisons using different flags.
c.le.d [$freg / imm], $freg, $freg
FP compare less or equal (double) : Sets FP condition flag 0 to true if $f2 <= $f4 (double-precision), false otherwise. Both register numbers must be even.
FP compare less or equal (double, flagged) : Sets FP condition flag N (specified by the first operand) to true if $f2 <= $f4 (double-precision), false otherwise. Both register numbers must be even.
c.le.s [$freg / imm], $freg, $freg
FP compare less or equal (single) : Sets FP condition flag 0 to true if $f0 <= $f1 (single-precision), false otherwise.
FP compare less or equal (single, flagged) : Sets FP condition flag N (specified by the first operand) to true if $f0 <= $f1 (single-precision), false otherwise.
c.lt.d [$freg / imm], $freg, $freg
FP compare less than (double) : Sets FP condition flag 0 to true if $f2 < $f4 (double-precision), false otherwise. Both register numbers must be even.
FP compare less than (double, flagged) : Sets FP condition flag N (specified by the first operand) to true if $f2 < $f4 (double-precision), false otherwise. Both register numbers must be even.
c.lt.s [$freg / imm], $freg, $freg
FP compare less than (single) : Sets FP condition flag 0 to true if $f0 < $f1 (single-precision), false otherwise.
FP compare less than (single, flagged) : Sets FP condition flag N (specified by the first operand) to true if $f0 < $f1 (single-precision), false otherwise.
ceil.w.d $freg, $freg
Ceiling double-precision to word : Converts the double-precision float in $f2 (even-numbered register) to a 32-bit integer by rounding toward positive infinity, storing the result in $f1.
ceil.w.s $freg, $freg
Ceiling single-precision to word : Converts the single-precision float in $f1 to a 32-bit integer by rounding toward positive infinity, and stores the result in $f0.
clo $reg, $reg
Count leading ones : Sets $t1 to the number of consecutive 1 bits in $t2, counted from the most-significant bit downward. For example, if $t2 = 0b11100000..., then $t1 = 3. Returns 32 if all bits are 1.
clz $reg, $reg
Count leading zeros : Sets $t1 to the number of consecutive 0 bits in $t2, counted from the most-significant bit downward. For example, if $t2 = 0b00010000..., then $t1 = 3. Returns 32 if $t2 is 0. Often used to compute floor(log2(n)) or to normalize values.
cvt.d.s $freg, $freg
Convert single-precision to double-precision : Converts the single-precision float in $f1 to double-precision (64-bit IEEE 754) and stores the result in $f2. $f2 must be even-numbered. No data is lost because double has more precision.
cvt.d.w $freg, $freg
Convert integer word to double-precision : Treats the 32-bit integer stored in $f1 as a signed integer and converts it to a double-precision float stored in $f2. $f2 must be even-numbered.
cvt.s.d $freg, $freg
Convert double-precision to single-precision : Converts the double-precision float in $f2 to single-precision and stores the result in $f1. $f2 must be even-numbered. Precision may be lost since single has fewer significant digits.
cvt.s.w $freg, $freg
Convert integer word to single-precision : Treats the 32-bit integer stored in $f1 as a signed integer and converts it to a single-precision float stored in $f0.
cvt.w.d $freg, $freg
Convert double-precision to integer word : Converts the double-precision float in $f2 to a signed 32-bit integer by truncation and stores the result in $f1. $f2 must be even-numbered. Use 'mfc1' to move the integer result to a general-purpose register.
cvt.w.s $freg, $freg
Convert single-precision to integer word : Converts the single-precision float in $f1 to a signed 32-bit integer by truncation and stores the result in $f0. Use 'mfc1' to move the integer result to a general-purpose register.
div $reg, $reg, [$reg / imm]
Divide signed : Divides $t1 by $t2 (signed). Sets LO to the quotient and HI to the remainder. Division by zero produces undefined results with no exception. Use 'mflo' to get the quotient; 'mfhi' to get the remainder.
DIVision : Set $t1 to ($t2 divided by $t3, integer division)
DIVision : Set $t1 to ($t2 divided by 16-bit immediate, integer division)
DIVision : Set $t1 to ($t2 divided by 32-bit immediate, integer division)
div.d $freg, $freg, $freg
Floating-point divide (double) : Sets $f2 = $f4 / $f6 using IEEE 754 double-precision (64-bit) arithmetic. All register numbers must be even.
div.s $freg, $freg, $freg
Floating-point divide (single) : Sets $f0 = $f1 / $f3 using IEEE 754 single-precision (32-bit) arithmetic. Dividing by zero produces +/-Infinity according to IEEE 754.
divu $reg, $reg, [$reg / imm]
Divide unsigned : Divides $t1 by $t2 treating both as unsigned 32-bit integers. Sets LO to the quotient and HI to the remainder. Division by zero produces undefined results with no exception. Use 'mflo' for the quotient; 'mfhi' for the remainder.
DIVision Unsigned : Set $t1 to ($t2 divided by $t3, unsigned integer division)
DIVision Unsigned : Set $t1 to ($t2 divided by 16-bit immediate, unsigned integer division)
DIVision Unsigned : Set $t1 to ($t2 divided by 32-bit immediate, unsigned integer division)
eret
Exception return : Returns from an exception or interrupt handler. Restores the PC from the EPC register (Coprocessor 0 register 14) and clears the Exception Level bit (bit 1) in the Status register, re-enabling interrupts and returning to user mode.
floor.w.d $freg, $freg
Floor double-precision to word : Converts the double-precision float in $f2 (even-numbered register) to a 32-bit integer by rounding toward negative infinity, storing the result in $f1.
floor.w.s $freg, $freg
Floor single-precision to word : Converts the single-precision float in $f1 to a 32-bit integer by rounding toward negative infinity (i.e., always truncates toward -inf), and stores the result in $f0. Use 'mfc1' to move the result to a general-purpose register.
j id
Jump unconditionally : Transfers execution to 'target'. The destination is encoded as a 26-bit word address; the upper 4 bits of PC are combined with this value, so the target must be in the same 256 MB region as the instruction following the jump.
jal id
Jump and link : Saves the return address (PC + 4) in $ra, then jumps to 'target'. The standard function-call instruction in MIPS. The called function returns with 'jr $ra'. Same address-range restriction as 'j'.
jalr $reg, $reg
Jump and link register : Saves the return address (PC + 4) in $t1, then jumps to the address in $t2. Allows calling a function whose address is only known at runtime (function pointer). Return with 'jr $t1'.
Jump and link register : Saves the return address (PC + 4) in $ra, then jumps to the address in $t1. One-operand shorthand for 'jalr $ra,$t1'. Used to call a function via a pointer stored in a register.
jr $reg
Jump register : Transfers execution to the address stored in $t1. Most commonly used as 'jr $ra' to return from a function call made with 'jal' or 'jalr'.
l.d $freg, [($reg) / imm / imm($reg) / id / id($reg) / id+imm / id+imm($reg)]
Load floating point Double precision : Set $f2 and $f3 register pair to 64-bit value at effective memory doubleword address
l.s $freg, [($reg) / imm / imm($reg) / id / id($reg) / id+imm / id+imm($reg)]
Load floating point Single precision : Set $f1 to 32-bit value at effective memory word address
la $reg, [($reg) / imm / imm($reg) / id / id($reg) / id+imm / id+imm($reg)]
Load Address : Set $t1 to contents of $t2
Load Address : Set $t1 to 16-bit immediate (sign-extended)
Load Address : Set $t1 to 16-bit immediate (zero-extended)
Load Address : Set $t1 to 32-bit immediate
Load Address : Set $t1 to sum (of $t2 and 16-bit immediate)
Load Address : Set $t1 to sum (of $t2 and 32-bit immediate)
Load Address : Set $t1 to label's address
Load Address : Set $t1 to sum (of $t2 and label's address)
Load Address : Set $t1 to sum (of label's address and 32-bit immediate)
Load Address : Set $t1 to sum (of label's address, 32-bit immediate, and $t2)
lb $reg, [imm($reg) / ($reg) / imm / id / id($reg) / id+imm / id+imm($reg)]
Load byte (sign-extended) : Reads one byte from memory at address ($t2 + offset), sign-extends it to 32 bits, and stores the result in $t1. A byte with value 0xFF becomes -1 (0xFFFFFFFF) in $t1. Use 'lbu' if you want zero-extension (0 to 255 range).
Load Byte : Set $t1 to sign-extended 8-bit value from effective memory byte address
lbu $reg, [imm($reg) / ($reg) / imm / id / id($reg) / id+imm / id+imm($reg)]
Load byte unsigned (zero-extended) : Reads one byte from memory at address ($t2 + offset), zero-extends it to 32 bits (upper 24 bits of $t1 are always 0), and stores the result in $t1. Values range from 0 to 255. Use 'lb' if you need sign-extension.
Load Byte Unsigned : Set $t1 to zero-extended 8-bit value from effective memory byte address
ld $reg, [imm($reg) / imm / id / id+imm / ($reg) / id($reg) / id+imm($reg)]
Load Doubleword : Set $t1 and the next register to the 64 bits starting at effective memory byte address
Load Doubleword : Set $t1 and the next register to the 64 bits starting at effective memory word address
ldc1 $freg, [imm($reg) / ($reg) / imm / id / id($reg) / id+imm / id+imm($reg)]
Load doubleword to FP register pair : Loads a 64-bit value from memory at address ($t2 + offset) into the even FP register pair $f2/$f3. Used to load a double-precision float from memory. Address must be doubleword-aligned and $f2 must be even-numbered.
Load Doubleword Coprocessor 1 : Set $f2 and $f3 register pair to 64-bit value at effective memory doubleword address
lh $reg, [imm($reg) / ($reg) / imm / id / id($reg) / id+imm / id+imm($reg)]
Load halfword (sign-extended) : Reads a 16-bit value from memory at address ($t2 + offset), sign-extends it to 32 bits, and stores the result in $t1. The address must be halfword-aligned (divisible by 2). Use 'lhu' for zero-extension.
Load Halfword : Set $t1 to sign-extended 16-bit value from effective memory halfword address
lhu $reg, [imm($reg) / ($reg) / imm / id / id($reg) / id+imm / id+imm($reg)]
Load halfword unsigned (zero-extended) : Reads a 16-bit value from memory at address ($t2 + offset), zero-extends it to 32 bits (upper 16 bits of $t1 are always 0), and stores the result in $t1. The address must be halfword-aligned (divisible by 2).
Load Halfword Unsigned : Set $t1 to zero-extended 16-bit value from effective memory halfword address
li $reg, imm
Load Immediate : Set $t1 to 16-bit immediate (sign-extended)
Load Immediate : Set $t1 to unsigned 16-bit immediate (zero-extended)
Load Immediate : Set $t1 to 32-bit immediate
ll $reg, [imm($reg) / ($reg) / imm / id / id($reg) / id+imm / id+imm($reg)]
Load linked : Identical to 'lw' in this simulator (reads 32 bits from memory into $t1). In real multi-processor hardware, 'll' is the first half of an atomic read-modify-write pair with 'sc' (store conditional), allowing lock-free synchronization.
Load Linked : Paired with Store Conditional (sc) to perform atomic read-modify-write. Treated as equivalent to Load Word (lw) because MARS does not simulate multiple processors.
lui $reg, imm
Load upper immediate : Places the 16-bit immediate into the upper 16 bits of $t1 and clears the lower 16 bits to 0. Used to build a full 32-bit constant: first 'lui $t1,upper16' then 'ori $t1,$t1,lower16'. Example: to load 0x12345678 use 'lui $t1,0x1234' then 'ori $t1,$t1,0x5678'.
lw $reg, [imm($reg) / ($reg) / imm / id / id($reg) / id+imm / id+imm($reg)]
Load word : Reads the 32-bit (4-byte) value at memory address ($t2 + offset) and places it in $t1. The address must be word-aligned (divisible by 4). Example: 'lw $t0,0($sp)' loads the value at the top of the stack.
Load Word : Set $t1 to contents of effective memory word address
Load Word : Set $t1 to contents of memory word at label's address
Load Word : Set $t1 to contents of effective memory word address
lwc1 $freg, [imm($reg) / ($reg) / imm / id / id($reg) / id+imm / id+imm($reg)]
Load word to FP register : Loads a 32-bit value from memory at address ($t2 + offset) directly into FP register $f1. Typically used to load a single-precision float from memory. Address must be word-aligned.
Load Word Coprocessor 1 : Set $f1 to 32-bit value from effective memory word address
lwl $reg, [imm($reg) / ($reg) / imm / id / id($reg) / id+imm / id+imm($reg)]
Load word left (unaligned) : Loads 1-4 bytes into the most-significant (left) bytes of $t1 starting from the effective byte address and working toward the low byte of the containing word. Use together with 'lwr' to load a full 32-bit word from an unaligned address.
Load Word Left : Load from 1 to 4 bytes left-justified into $t1, starting with effective memory byte address and continuing through the low-order byte of its word
lwr $reg, [imm($reg) / ($reg) / imm / id / id($reg) / id+imm / id+imm($reg)]
Load word right (unaligned) : Loads 1-4 bytes into the least-significant (right) bytes of $t1 starting from the effective byte address and working toward the high byte of the containing word. Use together with 'lwl' to load a full 32-bit word from an unaligned address.
Load Word Right : Load from 1 to 4 bytes right-justified into $t1, starting with effective memory byte address and continuing through the high-order byte of its word
madd $reg, $reg
Multiply-accumulate signed : Multiplies $t1 by $t2 (signed) to form a 64-bit product, then adds that product to the current 64-bit value in HI:LO. Useful for computing dot-products or sums of products without extra move instructions.
maddu $reg, $reg
Multiply-accumulate unsigned : Multiplies $t1 by $t2 treating both as unsigned 32-bit integers, then adds the 64-bit product to HI:LO. Use 'mfhi'/'mflo' to read the accumulated result.
mfc0 $reg, regnum
Move from Coprocessor 0 : Reads a Coprocessor 0 (CP0) control register and places its value in general-purpose register $t1. CP0 registers hold exception/interrupt state: register 8 (BadVAddr), 12 (Status), 13 (Cause), 14 (EPC), etc.
mfc1 $reg, $freg
Move from FP register to integer register : Copies the raw 32-bit bit-pattern stored in FP register $f1 into integer register $t1. Useful for reading a single-precision float's bits or the result of 'floor.w.s', 'cvt.w.s', etc.
mfc1.d $reg, $freg
Move From Coprocessor 1 Double : Set $t1 to contents of $f2, set next higher register from $t1 to contents of next higher register from $f2
mfhi $reg
Move from HI : Copies the special HI register into $t1. HI holds the upper 32 bits of a multiply result or the remainder from a divide. Always read HI/LO before executing another multiply or divide, as those instructions overwrite them.
mflo $reg
Move from LO : Copies the special LO register into $t1. LO holds the lower 32 bits of a multiply result or the quotient from a divide. Always read HI/LO before executing another multiply or divide, as those instructions overwrite them.
mov.d $freg, $freg
Move double-precision FP register : Copies the double-precision value in $f4 into $f2. Both register numbers must be even. Does not perform any conversion.
mov.s $freg, $freg
Move single-precision FP register : Copies the single-precision value in $f1 into $f0. Does not perform any conversion.
move $reg, $reg
MOVE : Set $t1 to contents of $t2
movf $reg, $reg, imm
Move if FP condition flag 0 is false : Copies $t2 into $t1 if floating-point condition flag 0 is false (0). Allows integer register updates to be conditioned on the result of a previous FP comparison (e.g., c.eq.s, c.lt.s).
Move if specified FP condition flag is false : Copies $t2 into $t1 if FP condition flag N (specified by the third operand) is false (0). Allows results of multiple simultaneous FP comparisons to control integer register moves.
movf.d $freg, $freg, imm
Move double-precision FP if condition flag 0 is false : Copies the double-precision value in $f4 into $f2 if FP condition flag 0 is false (0). Both register numbers must be even.
Move double-precision FP if specified condition flag is false : Copies the double-precision value in $f4 into $f2 if FP condition flag N (specified by the immediate) is false (0). Both register numbers must be even.
movf.s $freg, $freg, imm
Move single-precision FP if condition flag 0 is false : Copies the single-precision value in $f1 into $f0 if FP condition flag 0 is false (0).
Move single-precision FP if specified condition flag is false : Copies the single-precision value in $f1 into $f0 if FP condition flag N (specified by the immediate) is false (0).
movn $reg, $reg, $reg
Move if not zero : Copies $t2 into $t1 only if $t3 != 0. Allows branchless conditional assignment — avoids a branch instruction when you only need to update a register conditionally.
movn.d $freg, $freg, $reg
Move double-precision FP if integer register not zero : Copies the double-precision value in $f4 into $f2 if $t3 != 0. Both FP register numbers must be even.
movn.s $freg, $freg, $reg
Move single-precision FP if integer register not zero : Copies the single-precision value in $f1 into $f0 if $t3 != 0.
movt $reg, $reg, imm
Move if FP condition flag 0 is true : Copies $t2 into $t1 if floating-point condition flag 0 is true (1). Allows integer register updates to be conditioned on the result of a previous FP comparison (e.g., c.eq.s, c.lt.s).
Move if specified FP condition flag is true : Copies $t2 into $t1 if FP condition flag N (specified by the third operand) is true (1). Allows results of multiple simultaneous FP comparisons to control integer register moves.
movt.d $freg, $freg, imm
Move double-precision FP if condition flag 0 is true : Copies the double-precision value in $f4 into $f2 if FP condition flag 0 is true (1). Both register numbers must be even.
Move double-precision FP if specified condition flag is true : Copies the double-precision value in $f4 into $f2 if FP condition flag N (specified by the immediate) is true (1). Both register numbers must be even.
movt.s $freg, $freg, imm
Move single-precision FP if condition flag 0 is true : Copies the single-precision value in $f1 into $f0 if FP condition flag 0 is true (1).
Move single-precision FP if specified condition flag is true : Copies the single-precision value in $f1 into $f0 if FP condition flag N (specified by the immediate) is true (1).
movz $reg, $reg, $reg
Move if zero : Copies $t2 into $t1 only if $t3 == 0. Allows branchless conditional assignment — avoids a branch instruction when you only need to update a register conditionally.
movz.d $freg, $freg, $reg
Move double-precision FP if integer register is zero : Copies the double-precision value in $f4 into $f2 if $t3 == 0. Both FP register numbers must be even.
movz.s $freg, $freg, $reg
Move single-precision FP if integer register is zero : Copies the single-precision value in $f1 into $f0 if $t3 == 0.
msub $reg, $reg
Multiply-subtract signed : Multiplies $t1 by $t2 (signed) to form a 64-bit product, then subtracts that product from the current 64-bit value in HI:LO. Use 'mfhi'/'mflo' to read the result.
msubu $reg, $reg
Multiply-subtract unsigned : Multiplies $t1 by $t2 treating both as unsigned 32-bit integers, then subtracts the 64-bit product from HI:LO. Use 'mfhi'/'mflo' to read the result.
mtc0 $reg, regnum
Move to Coprocessor 0 : Writes the value of general-purpose register $t1 into a Coprocessor 0 (CP0) control register. Used by exception handlers to modify the Status and Cause registers or to clear the EPC.
mtc1 $reg, $freg
Move from integer register to FP register : Copies the 32-bit value in integer register $t1 into FP register $f1 without any conversion. Useful for initializing a FP register with a specific bit pattern or loading a freshly-computed integer before 'cvt.s.w'.
mtc1.d $reg, $freg
Move To Coprocessor 1 Double : Set $f2 to contents of $t1, set next higher register from $f2 to contents of next higher register from $t1
mthi $reg
Move to HI : Copies $t1 into the special HI register, overwriting any prior multiply or divide result stored there.
mtlo $reg
Move to LO : Copies $t1 into the special LO register, overwriting any prior multiply or divide result stored there.
mul $reg, $reg, [$reg / imm]
Multiply (low 32-bit result to register) : Multiplies $t2 by $t3 (signed) and stores the lower 32 bits of the product directly into $t1 and also into LO. No overflow exception is raised. HI is updated with the upper 32 bits.
MULtiplication : Set HI to high-order 32 bits, LO and $t1 to low-order 32 bits of the product of $t2 and 16-bit signed immediate (use mfhi to access HI, mflo to access LO)
MULtiplication : Set HI to high-order 32 bits, LO and $t1 to low-order 32 bits of the product of $t2 and 32-bit immediate (use mfhi to access HI, mflo to access LO)
mul.d $freg, $freg, $freg
Floating-point multiply (double) : Sets $f2 = $f4 * $f6 using IEEE 754 double-precision (64-bit) arithmetic. All register numbers must be even.
mul.s $freg, $freg, $freg
Floating-point multiply (single) : Sets $f0 = $f1 * $f3 using IEEE 754 single-precision (32-bit) arithmetic.
mulo $reg, $reg, [$reg / imm]
MULtiplication with Overflow : Set $t1 to low-order 32 bits of the product of $t2 and $t3
MULtiplication with Overflow : Set $t1 to low-order 32 bits of the product of $t2 and signed 16-bit immediate
MULtiplication with Overflow : Set $t1 to low-order 32 bits of the product of $t2 and 32-bit immediate
mulou $reg, $reg, [$reg / imm]
MULtiplication with Overflow Unsigned : Set $t1 to low-order 32 bits of the product of $t2 and $t3
MULtiplication with Overflow Unsigned : Set $t1 to low-order 32 bits of the product of $t2 and signed 16-bit immediate
MULtiplication with Overflow Unsigned : Set $t1 to low-order 32 bits of the product of $t2 and 32-bit immediate
mult $reg, $reg
Multiply signed : Multiplies $t1 by $t2 as signed 32-bit integers. The 64-bit product is split: the upper 32 bits go into the HI register and the lower 32 bits go into the LO register. Use 'mfhi' to read HI and 'mflo' to read LO.
multu $reg, $reg
Multiply unsigned : Multiplies $t1 by $t2 treating both as unsigned 32-bit integers. The 64-bit product is split: upper 32 bits go into HI, lower 32 bits go into LO. Use 'mfhi'/'mflo' to retrieve the results.
mulu $reg, $reg, [$reg / imm]
MULtiplication Unsigned : Set HI to high-order 32 bits, LO and $t1 to low-order 32 bits of ($t2 multiplied by $t3, unsigned multiplication)
MULtiplication Unsigned : Set HI to high-order 32 bits, LO and $t1 to low-order 32 bits of ($t2 multiplied by 16-bit immediate, unsigned multiplication)
MULtiplication Unsigned : Set HI to high-order 32 bits, LO and $t1 to low-order 32 bits of ($t2 multiplied by 32-bit immediate, unsigned multiplication)
neg $reg, $reg
NEGate : Set $t1 to negation of $t2
neg.d $freg, $freg
Floating-point negate (double) : Sets $f2 to the negation of $f4 (double-precision) by flipping the sign bit. Both register numbers must be even.
neg.s $freg, $freg
Floating-point negate (single) : Sets $f0 to the negation of $f1 (single-precision) by flipping the sign bit.
negu $reg, $reg
NEGate Unsigned : Set $t1 to negation of $t2, no overflow
nop
No operation : Does nothing; the processor simply advances to the next instruction. Machine code is all zeroes. Useful as a placeholder or delay-slot filler.
nor $reg, $reg, $reg
Bitwise NOR : Sets $t1 = ~($t2 | $t3). Each bit of $t1 is 1 only if the corresponding bit is 0 in both $t2 and $t3. Tip: 'nor $t1,$t2,$zero' computes a bitwise NOT of $t2, since MIPS has no dedicated NOT instruction.
not $reg, $reg
Bitwise NOT (bit inversion)
or $reg, [$reg / imm], [$reg / imm]
Bitwise OR : Sets $t1 = $t2 | $t3. Each bit of $t1 is 1 if the corresponding bit is 1 in either $t2 or $t3 (or both). Commonly used to set specific bits in a value.
OR : set $t1 to ($t2 bitwise-OR 16-bit unsigned immediate)
OR : set $t1 to ($t1 bitwise-OR 16-bit unsigned immediate)
ori $reg, [$reg / imm], imm
Bitwise OR immediate : Sets $t1 = $t2 | immediate. The 16-bit immediate is zero-extended before the OR. Commonly used to set specific bits or to load a small non-negative constant into a register (e.g. after 'lui').
OR Immediate : set $t1 to ($t2 bitwise-OR 32-bit immediate)
OR Immediate : set $t1 to ($t1 bitwise-OR 16-bit unsigned immediate)
OR Immediate : set $t1 to ($t1 bitwise-OR 32-bit immediate)
rem $reg, $reg, [$reg / imm]
REMainder : Set $t1 to (remainder of $t2 divided by $t3)
REMainder : Set $t1 to (remainder of $t2 divided by 16-bit immediate)
REMainder : Set $t1 to (remainder of $t2 divided by 32-bit immediate)
remu $reg, $reg, [$reg / imm]
REMainder : Set $t1 to (remainder of $t2 divided by $t3, unsigned division)
REMainder : Set $t1 to (remainder of $t2 divided by 16-bit immediate, unsigned division)
REMainder : Set $t1 to (remainder of $t2 divided by 32-bit immediate, unsigned division)
rol $reg, $reg, [$reg / imm]
ROtate Left : Set $t1 to ($t2 rotated left by number of bit positions specified in $t3)
ROtate Left : Set $t1 to ($t2 rotated left by number of bit positions specified in 5-bit immediate)
ror $reg, $reg, [$reg / imm]
ROtate Right : Set $t1 to ($t2 rotated right by number of bit positions specified in $t3)
ROtate Right : Set $t1 to ($t2 rotated right by number of bit positions specified in 5-bit immediate)
round.w.d $freg, $freg
Round double-precision to word : Converts the double-precision float in $f2 (even-numbered register) to the nearest 32-bit integer (round half to even, per IEEE 754), storing the result in $f1.
round.w.s $freg, $freg
Round single-precision to word : Converts the single-precision float in $f1 to the nearest 32-bit integer (round half to even, per IEEE 754), and stores the result in $f0.
s.d $freg, [($reg) / imm / imm($reg) / id / id($reg) / id+imm / id+imm($reg)]
Store floating point Double precision : Store 64 bits from $f2 and $f3 register pair to effective memory doubleword address
s.s $freg, [($reg) / imm / imm($reg) / id / id($reg) / id+imm / id+imm($reg)]
Store floating point Single precision : Store 32-bit value from $f1 to effective memory word address
sb $reg, [imm($reg) / ($reg) / imm / id / id($reg) / id+imm / id+imm($reg)]
Store byte : Writes the lowest 8 bits of $t1 to memory at address ($t2 + offset). The upper 24 bits of $t1 are ignored. Useful for writing single characters or packed byte arrays.
Store Byte : Store the low-order 8 bits of $t1 into the effective memory byte address
sc $reg, [imm($reg) / ($reg) / imm / id / id($reg) / id+imm / id+imm($reg)]
Store conditional : Stores the value of $t1 into memory at address ($t2 + offset), then sets $t1 = 1 (success). In real multi-processor hardware this can fail (setting $t1 = 0) if another processor modified the target location since the preceding 'll'. Always succeeds in this simulator.
Store Conditional : Paired with Load Linked (ll) to perform atomic read-modify-write. Treated as equivalent to Store Word (sw) because MARS does not simulate multiple processors.
sd $reg, [imm($reg) / imm / id / id+imm / ($reg) / id($reg) / id+imm($reg)]
Store Doubleword : Store contents of $t1 and the next register to the 64 bits starting at effective memory byte address
Store Doubleword : Store contents of $t1 and the next register to the 64 bits starting at effective memory word address
sdc1 $freg, [imm($reg) / ($reg) / imm / id / id($reg) / id+imm / id+imm($reg)]
Store doubleword from FP register pair : Writes the 64-bit value in the even FP register pair $f2/$f3 to memory at address ($t2 + offset). Used to store a double-precision float to memory. Address must be doubleword-aligned and $f2 must be even-numbered.
Store Doubleword Coprocessor 1 : Store 64 bits from $f2 and $f3 register pair to effective memory doubleword address
seq $reg, $reg, [$reg / imm]
Set EQual : if $t2 equal to $t3 then set $t1 to 1 else 0
Set EQual : if $t2 equal to 16-bit immediate then set $t1 to 1 else 0
Set EQual : if $t2 equal to 32-bit immediate then set $t1 to 1 else 0
sge $reg, $reg, [$reg / imm]
Set Greater or Equal : if $t2 greater or equal to $t3 then set $t1 to 1 else 0
Set Greater or Equal : if $t2 greater or equal to 16-bit immediate then set $t1 to 1 else 0
Set Greater or Equal : if $t2 greater or equal to 32-bit immediate then set $t1 to 1 else 0
sgeu $reg, $reg, [$reg / imm]
Set Greater or Equal Unsigned : if $t2 greater or equal to $t3 (unsigned compare) then set $t1 to 1 else 0
Set Greater or Equal Unsigned : if $t2 greater or equal to 16-bit immediate (unsigned compare) then set $t1 to 1 else 0
Set Greater or Equal Unsigned : if $t2 greater or equal to 32-bit immediate (unsigned compare) then set $t1 to 1 else 0
sgt $reg, $reg, [$reg / imm]
Set Greater Than : if $t2 greater than $t3 then set $t1 to 1 else 0
Set Greater Than : if $t2 greater than 16-bit immediate then set $t1 to 1 else 0
Set Greater Than : if $t2 greater than 32-bit immediate then set $t1 to 1 else 0
sgtu $reg, $reg, [$reg / imm]
Set Greater Than Unsigned : if $t2 greater than $t3 (unsigned compare) then set $t1 to 1 else 0
Set Greater Than Unsigned : if $t2 greater than 16-bit immediate (unsigned compare) then set $t1 to 1 else 0
Set Greater Than Unsigned : if $t2 greater than 32-bit immediate (unsigned compare) then set $t1 to 1 else 0
sh $reg, [imm($reg) / ($reg) / imm / id / id($reg) / id+imm / id+imm($reg)]
Store halfword : Writes the lowest 16 bits of $t1 to memory at address ($t2 + offset). The upper 16 bits of $t1 are ignored. The address must be halfword-aligned (divisible by 2).
Store Halfword : Store the low-order 16 bits of $t1 into the effective memory halfword address
sle $reg, $reg, [$reg / imm]
Set Less or Equal : if $t2 less or equal to $t3 then set $t1 to 1 else 0
Set Less or Equal : if $t2 less or equal to 16-bit immediate then set $t1 to 1 else 0
Set Less or Equal : if $t2 less or equal to 32-bit immediate then set $t1 to 1 else 0
sleu $reg, $reg, [$reg / imm]
Set Less or Equal Unsigned: if $t2 less or equal to $t3 (unsigned compare) then set $t1 to 1 else 0
Set Less or Equal Unsigned: if $t2 less or equal to 16-bit immediate (unsigned compare) then set $t1 to 1 else 0
Set Less or Equal Unsigned: if $t2 less or equal to 32-bit immediate (unsigned compare) then set $t1 to 1 else 0
sll $reg, $reg, imm
Shift left logical : Sets $t1 = $t2 << immediate (0-31 bits). Vacated bits on the right are filled with 0. Shifting left by n is equivalent to multiplying by 2^n (without overflow checking). Example: sll $t1,$t1,2 multiplies $t1 by 4.
sllv $reg, $reg, $reg
Shift left logical variable : Sets $t1 = $t2 << ($t3 & 31). Like 'sll' but the shift amount is taken from the lowest 5 bits of register $t3 rather than an immediate constant. The upper 27 bits of $t3 are ignored.
slt $reg, $reg, $reg
Set on less than (signed) : Sets $t1 = 1 if $t2 < $t3 (signed comparison), otherwise $t1 = 0. Useful for conditional logic without branches. Pair with 'bne $t1,$zero,label' or 'beq $t1,$zero,label' to branch on the result.
slti $reg, $reg, imm
Set on less than immediate (signed) : Sets $t1 = 1 if $t2 < immediate (sign-extended to 32 bits), otherwise $t1 = 0. Convenient for loop bounds and range checking without a separate load instruction.
sltiu $reg, $reg, imm
Set on less than immediate unsigned : Sets $t1 = 1 if $t2 < immediate using unsigned comparison. The immediate is sign-extended to 32 bits first, then interpreted as unsigned. Commonly used to test if a value is below a limit without needing a separate register.
sltu $reg, $reg, $reg
Set on less than unsigned : Sets $t1 = 1 if $t2 < $t3 using unsigned comparison, otherwise $t1 = 0. Treats both operands as unsigned 32-bit integers (0 to 4294967295). Use this when comparing memory addresses or unsigned counters.
sne $reg, $reg, [$reg / imm]
Set Not Equal : if $t2 not equal to $t3 then set $t1 to 1 else 0
Set Not Equal : if $t2 not equal to 16-bit immediate then set $t1 to 1 else 0
Set Not Equal : if $t2 not equal to 32-bit immediate then set $t1 to 1 else 0
sqrt.d $freg, $freg
Floating-point square root (double) : Sets $f2 = sqrt($f4) using double-precision arithmetic. Both register numbers must be even. Returns NaN if $f4 is negative.
sqrt.s $freg, $freg
Floating-point square root (single) : Sets $f0 = sqrt($f1) using single-precision arithmetic. Returns NaN if $f1 is negative.
sra $reg, $reg, imm
Shift right arithmetic : Sets $t1 = $t2 >> immediate (0-31 bits). Vacated bits on the left are filled with copies of the sign bit, preserving the sign of negative numbers. Shifting right by n is equivalent to signed division by 2^n rounding toward negative infinity.
srav $reg, $reg, $reg
Shift right arithmetic variable : Sets $t1 = $t2 >> ($t3 & 31). Like 'sra' but the shift amount is taken from the lowest 5 bits of register $t3. Vacated bits are sign-filled.
srl $reg, $reg, imm
Shift right logical : Sets $t1 = $t2 >>> immediate (0-31 bits). Vacated bits on the left are filled with 0 (unsigned shift). Shifting right by n is equivalent to unsigned division by 2^n. Use 'sra' to preserve the sign bit instead.
srlv $reg, $reg, $reg
Shift right logical variable : Sets $t1 = $t2 >>> ($t3 & 31). Like 'srl' but the shift amount is taken from the lowest 5 bits of register $t3 rather than an immediate constant. Vacated bits are zero-filled.
sub $reg, $reg, [$reg / imm]
Subtract (signed, overflow trap) : Sets $t1 = $t2 - $t3 using signed 32-bit arithmetic. Raises an overflow exception if the true result does not fit in 32 bits. Use 'subu' when overflow should be silently ignored.
SUBtraction : set $t1 to ($t2 minus 16-bit immediate)
SUBtraction : set $t1 to ($t2 minus 32-bit immediate)
sub.d $freg, $freg, $freg
Floating-point subtract (double) : Sets $f2 = $f4 - $f6 using IEEE 754 double-precision (64-bit) arithmetic. All register numbers must be even.
sub.s $freg, $freg, $freg
Floating-point subtract (single) : Sets $f0 = $f1 - $f3 using IEEE 754 single-precision (32-bit) arithmetic.
subi $reg, $reg, imm
SUBtraction Immediate : set $t1 to ($t2 minus 16-bit immediate)
SUBtraction Immediate : set $t1 to ($t2 minus 32-bit immediate)
subiu $reg, $reg, imm
SUBtraction Immediate Unsigned : set $t1 to ($t2 minus 32-bit immediate), no overflow
subu $reg, $reg, [$reg / imm]
Subtract unsigned (no overflow trap) : Sets $t1 = $t2 - $t3. No exception is raised on overflow; the result wraps modulo 2^32. The most common subtract instruction in practice.
SUBtraction Unsigned : set $t1 to ($t2 minus 32-bit immediate), no overflow
sw $reg, [imm($reg) / ($reg) / imm / id / id($reg) / id+imm / id+imm($reg)]
Store word : Writes the 32-bit value in $t1 to memory at address ($t2 + offset). The address must be word-aligned (divisible by 4). Example: 'sw $t0,0($sp)' stores a value at the top of the stack.
Store Word : Store $t1 contents into effective memory word address
Store Word : Store $t1 contents into memory word at label's address
swc1 $freg, [imm($reg) / ($reg) / imm / id / id($reg) / id+imm / id+imm($reg)]
Store word from FP register : Writes the 32-bit value in FP register $f1 to memory at address ($t2 + offset). Typically used to store a single-precision float to memory. Address must be word-aligned.
Store Word Coprocessor 1 : Store 32-bit value from $f1 to effective memory word address
swl $reg, [imm($reg) / ($reg) / imm / id / id($reg) / id+imm / id+imm($reg)]
Store word left (unaligned) : Writes 1-4 bytes from the most-significant (left) bytes of $t1 into memory starting at the effective byte address and working toward the low byte of the containing aligned word. Use together with 'swr' to store a full word at an unaligned address.
Store Word Left : Store high-order 1 to 4 bytes of $t1 into memory, starting with effective memory byte address and continuing through the low-order byte of its word
swr $reg, [imm($reg) / ($reg) / imm / id / id($reg) / id+imm / id+imm($reg)]
Store word right (unaligned) : Writes 1-4 bytes from the least-significant (right) bytes of $t1 into memory starting at the high byte of the containing aligned word and working toward the effective byte address. Use together with 'swl' to store a full word at an unaligned address.
Store Word Right : Store low-order 1 to 4 bytes of $t1 into memory, starting with high-order byte of word containing effective memory byte address and continuing through that byte address
syscall
System call : Invokes an OS service identified by the integer in $v0. Common services: 1=print integer ($a0), 4=print string (addr in $a0), 5=read integer (result in $v0), 8=read string ($a0=buf addr, $a1=len), 10=exit. See the Help menu for the full list.
teq $reg, $reg
Trap if equal : Raises a trap exception if $t1 == $t2. In MARS this halts execution. On real hardware it triggers a trap handler. Useful as a guarded assertion or to catch forbidden conditions (e.g., division by zero guard).
teqi $reg, imm
Trap if equal to immediate : Raises a trap exception if $t1 == immediate (sign-extended to 32 bits). Immediate variant of 'teq'. Useful for checking a register against a known constant at runtime.
tge $reg, $reg
Trap if greater or equal (signed) : Raises a trap exception if $t1 >= $t2 (signed comparison).
tgei $reg, imm
Trap if greater or equal to immediate (signed) : Raises a trap if $t1 >= immediate (sign-extended to 32 bits).
tgeiu $reg, imm
Trap if greater or equal to immediate (unsigned) : Raises a trap if $t1 >= immediate using unsigned comparison. The immediate is sign-extended to 32 bits then interpreted as unsigned.
tgeu $reg, $reg
Trap if greater or equal (unsigned) : Raises a trap exception if $t1 >= $t2 using unsigned comparison. Treats both values as unsigned 32-bit integers.
tlt $reg, $reg
Trap if less than (signed) : Raises a trap exception if $t1 < $t2 (signed comparison).
tlti $reg, imm
Trap if less than immediate (signed) : Raises a trap exception if $t1 < immediate (sign-extended to 32 bits).
tltiu $reg, imm
Trap if less than immediate (unsigned) : Raises a trap exception if $t1 < immediate using unsigned comparison. The immediate is sign-extended to 32 bits then interpreted as unsigned.
tltu $reg, $reg
Trap if less than (unsigned) : Raises a trap exception if $t1 < $t2 using unsigned comparison.
tne $reg, $reg
Trap if not equal : Raises a trap exception if $t1 != $t2. In MARS this halts execution. Opposite of 'teq'.
tnei $reg, imm
Trap if not equal to immediate : Raises a trap exception if $t1 != immediate (sign-extended to 32 bits).
trunc.w.d $freg, $freg
Truncate double-precision to word : Converts the double-precision float in $f2 (even-numbered register) to a 32-bit integer by rounding toward zero (dropping the fractional part), storing the result in $f1.
trunc.w.s $freg, $freg
Truncate single-precision to word : Converts the single-precision float in $f1 to a 32-bit integer by rounding toward zero (drops the fractional part), and stores the result in $f0. Equivalent to C-style (int) cast.
ulh $reg, [imm($reg) / imm / id / id+imm / ($reg) / id($reg) / id+imm($reg)]
Unaligned Load Halfword : Set $t1 to the 16 bits, sign-extended, starting at effective memory byte address
ulhu $reg, [imm($reg) / imm / id / id+imm / ($reg) / id($reg) / id+imm($reg)]
Unaligned Load Halfword : Set $t1 to the 16 bits, zero-extended, starting at effective memory byte address
ulw $reg, [imm($reg) / imm / id / id+imm / ($reg) / id($reg) / id+imm($reg)]
Unaligned Load Word : Set $t1 to the 32 bits starting at effective memory byte address
ush $reg, [imm($reg) / imm / id / id+imm / ($reg) / id($reg) / id+imm($reg)]
Unaligned Store Halfword: Store low-order halfword $t1 contents into the 16 bits starting at effective memory byte address
usw $reg, [imm($reg) / imm / id / id+imm / ($reg) / id($reg) / id+imm($reg)]
Unaligned Store Word : Store $t1 contents into the 32 bits starting at effective memory byte address
xor $reg, [$reg / imm], [$reg / imm]
Bitwise XOR (exclusive OR) : Sets $t1 = $t2 ^ $t3. Each bit of $t1 is 1 if the corresponding bits in $t2 and $t3 differ. Used to toggle specific bits, detect differences, or implement simple encryption/checksums.
XOR : set $t1 to ($t2 bitwise-exclusive-OR 16-bit unsigned immediate)
XOR : set $t1 to ($t1 bitwise-exclusive-OR 16-bit unsigned immediate)
xori $reg, [$reg / imm], imm
Bitwise XOR immediate : Sets $t1 = $t2 ^ immediate. The 16-bit immediate is zero-extended before the XOR. Useful for toggling specific bits.
XOR Immediate : set $t1 to ($t2 bitwise-exclusive-OR 32-bit immediate)
XOR Immediate : set $t1 to ($t1 bitwise-exclusive-OR 16-bit unsigned immediate)
XOR Immediate : set $t1 to ($t1 bitwise-exclusive-OR 32-bit immediate)
Directives
MIPS directives are used to define the structure of the program. They are not instructions that are executed by the CPU, but rather instructions that are used by the assembler to define the structure of the program.
.data
Declares a section for storing initialized data, such as variables.
.text
Declares a section for storing executable instructions. This is where program logic is written.
.kdata
Declares a section for storing kernel-mode initialized data.
.ktext
Declares a section for storing kernel-mode executable instructions.
.word
Allocates one or more 32-bit (4-byte) words in memory.
Example:
values: .word 1, 2, 3, 4
.half
Allocates one or more 16-bit (2-byte) halfwords in memory.
Example:
values: .half 1234, 5678
.byte
Allocates one or more 8-bit (1-byte) values in memory.
Example:
flags: .byte 0, 1, 1, 0
.float
Allocates a single-precision floating-point (32-bit) number in memory.
.double
Allocates a double-precision floating-point (64-bit) number in memory.
.asciiz
Stores a null-terminated string (C-style string).
Example:
message: .asciiz "Hello, world!"
.ascii
Stores a string without a null terminator. Useful when manually handling string length.
.space
Reserves a specified number of bytes in memory without initializing them.
Example:
buffer: .space 100 # Reserves 100 bytes
.align
Aligns the next data to a 2^n-byte boundary.
Example:
.align 2 # Aligns to a 4-byte boundary
.globl
Marks a symbol as global, making it accessible from other files.
Example:
.globl main # Makes 'main' visible to the linker
.extern
Declares a symbol that is defined in another file, specifying its size.
.macro
Defines a macro, which allows writing reusable code blocks.
.end_macro
Ends a macro definition.
.include
Includes an external assembly file.
Example:
.include "myfile.s"
.eqv
Defines a symbolic constant, similar to #define in C.
Example:
.eqv SIZE 10
.set
Configures assembler settings, such as allowing modifications to the $at register.
Example:
.set noat # Allows use of register $at
.bss
Declares an uninitialized data section, typically used for reserving large blocks of memory.
.org
Sets the location counter to a specific address, controlling where subsequent data or code is placed.
.ltorg
Forces the assembler to place literal pools (constants) at the current location.
..frame
Defines a function's stack frame structure, including base register, stack size, and return register.
.ent
Marks the start of a function for debugging or profiling purposes.
.end
Marks the end of an assembly file or function.
.local
Declares a symbol as local, meaning it is only accessible within the current file.
Syscalls
MIPS syscalls are used to make requests to the operating system. They are not instructions that are executed by the CPU, but rather instructions that are used by the simulator to make requests to the operating system.
Each syscall has a unique code that is used to identify it. You must put the syscall code
inside the the $v0 register before calling the syscall instruction.
As an example:
# Load the integer 42 into register $a0, which is
# the register that will be printed by the syscall
li $a0, 42
# Set the syscall code for printing an integer
li $v0, 1
syscall
1 - Print integer
Arguments
2 - Print float
Arguments
3 - Print double
Arguments
4 - Print string
Arguments
5 - Read integer
Result
6 - Read float
Result
7 - Read double
Result
8 - Read string
Service 8 - Follows semantics of UNIX 'fgets'. For specified length n, string can be no longer than n-1. If less than that, adds newline to end. In either case, then pads with null byte If n = 1, input is ignored and null byte placed at buffer address. If n < 1, input is ignored and nothing is written to the buffer.
Arguments
9 - Sbrk (allocate heap memory)
Result
Arguments
10 - Exit (terminate execution)
11 - Print character
Service 11 - Prints ASCII character corresponding to contents of low-order byte.
Arguments
12 - Read character
Result
13 - Open file
Service 13 - MARS implements three flag values: 0 for read-only, 1 for write-only with create, and 9 for write-only with create and append. It ignores mode. The returned file descriptor will be negative if the operation failed. MARS maintains file descriptors internally and allocates them starting with 3. File descriptors 0, 1 and 2 are always open for: reading from standard input, writing to standard output, and writing to standard error, respectively (new in release 4.3).
Result
Arguments
14 - Read from file
Services 13,14,15 - In MARS 3.7, the result register was changed to $v0 for SPIM compatability. It was previously $a0 as erroneously printed in Appendix B of Computer Organization and Design,.
Result
Arguments
15 - Write to file
Services 13,14,15 - In MARS 3.7, the result register was changed to $v0 for SPIM compatability. It was previously $a0 as erroneously printed in Appendix B of Computer Organization and Design,.
Result
Arguments
16 - Close file
Arguments
17 - Exit2 (terminate with value)
Service 17 - If the MIPS program is run under control of the MARS graphical interface (GUI), the exit code in $a0 is ignored.
Arguments
30 - Time (system time)
Service 30 - System time as milliseconds since 1 January 1970.
Result
34 - Print integer in hexadecimal
Displayed value is 8 hexadecimal digits, left-padding with zeroes if necessary.
Arguments
35 - Print integer in binary
Displayed value is 32 bits, left-padding with zeroes if necessary.
Arguments
36 - Print integer as unsigned
Displayed as unsigned decimal value.
Arguments
41 - Random int
Each stream (identified by $a0 contents) is modeled by a different Random object. There are no default seed values, so use the Set Seed service (40) if replicated random sequences are desired.
Result
Arguments
42 - Random int range
Each stream (identified by $a0 contents) is modeled by a different Random object. There are no default seed values, so use the Set Seed service (40) if replicated random sequences are desired.
Result
Arguments
43 - Random float
Each stream (identified by $a0 contents) is modeled by a different Random object. There are no default seed values, so use the Set Seed service (40) if replicated random sequences are desired.
Result
Arguments
44 - Random double
Each stream (identified by $a0 contents) is modeled by a different Random object. There are no default seed values, so use the Set Seed service (40) if replicated random sequences are desired.
Result
Arguments
50 - ConfirmDialog
Result
Arguments
51 - InputDialogInt
Result
Arguments
52 - InputDialogFloat
Result
Arguments
53 - InputDialogDouble
Result
Arguments
54 - InputDialogString
See Service 8 note below table
Result
Arguments
55 - MessageDialog
N/A
Arguments
56 - MessageDialogInt
N/A
Arguments
57 - MessageDialogFloat
N/A
Arguments
58 - MessageDialogDouble
N/A
Arguments
59 - MessageDialogString
N/A
Arguments
Registers
MIPS has 32 GPR registers each of 32 bits
$zero ($0)
Always contains the value 0. Any write attempt to this register is silently ignored.
$at ($1)
Assembly temporary, reserved for assembler internal use. It is used by macro instructions like li or la to break them into multiple real instructions. You can take control of it using the .set noat directive, but after that, macro instructions that rely on it will stop working.
$v0 - $v1 ($2 - $3)
Used to return non-floating point values from a subroutine. If the return value fits in 32 bits, only $v0 is used; for 64-bit values, the high word goes in $v1. $v0 also holds the system call number before a syscall instruction.
$a0 - $a3 ($4 - $7)
Arguments, used to pass the first four non-floating point arguments to a subroutine. Additional arguments are passed on the stack.
$t0 - $t7 ($8 - $15)
Temporary registers, their values are not preserved across subroutine calls. The caller is responsible for saving them if needed.
$s0 - $s7 ($16 - $23)
Saved registers, subroutines must preserve their values across calls, either by not using them or by saving and restoring them on the stack.
$t8 - $t9 ($24 - $25)
Additional temporary registers, same conventions as $t0-$t7. Note that $t9 has a special role in PIC code: by convention it holds the address of the called function, allowing the callee to compute $gp.
$k0 - $k1 ($26 - $27)
Reserved for OS/interrupt handler use. They can be overwritten at any time by an interrupt or trap handler, so user code should never rely on their values.
$gp ($28)
Global pointer, used for two distinct purposes. In PIC code (Linux shared libraries), it points to the GOT (Global Offset Table), a table of pointers that the dynamic loader fills at runtime with the real addresses of external symbols. In non-PIC code (embedded systems), it points to the center of a compact region of small global/static variables, allowing them to be accessed with a single instruction using a signed 16-bit offset (covering ±32KB, 64KB total).
$sp ($29)
Stack pointer, points to the top of the stack. It is explicitly adjusted by the callee on subroutine entry and exit.
$fp ($30)
Frame pointer, also known as $s8. Used by a subroutine to track the stack frame when the stack pointer cannot be used directly, for example when the stack size is not known at compile time (e.g. when using alloca()).
$ra ($31)
Return address, automatically written by jal with the address of the instruction following the call. The subroutine returns by executing jr $ra. Functions that themselves call other subroutines must save $ra on the stack first, since jal would otherwise overwrite it.