MIPS Instruction Formats, Registers and Machine Code, CS 2340 – Study Notes
offline

TL;DR

Every MIPS instruction is exactly 32 bits wide and comes in one of three formats: R-type (register operations), I-type (operations with an immediate value or memory access), and J-type (jumps). You need to know which format each instruction uses, what each field means, and how to convert between assembly and machine code (binary and hex) by hand.

Difficulty: Intermediate | Prerequisites: Binary number representation (see Part 1 notes).

Big Picture

The processor does not read "add $s1, $s2, $s3" as text. It reads a 32-bit binary number whose fields tell the hardware what operation to perform and which registers to use. Understanding instruction formats is how you bridge the gap between the assembly code you write and the machine code the CPU executes.

This topic is central to the exam. Around half the short-answer questions involve reading or writing machine code, and the multiple-choice section tests whether you know which fields belong to which format. If you can fluently move between assembly, binary, and hex, most of those questions become mechanical.


Key Terms

Opcode (operation code)

The first 6 bits (bits 31 to 26) of every MIPS instruction. It tells the processor the general category of the instruction. For R-type instructions, the opcode is 000000 and the specific operation is determined by the funct field.

R-type (register type)

An instruction format for operations that use only registers (no immediate values). Fields: opcode (6) | rs (5) | rt (5) | rd (5) | shamt (5) | funct (6). Think of it as the format for "register-to-register" work like add, sub, and, or, slt.

I-type (immediate type)

An instruction format for operations that include a constant (immediate) value, or for loads and stores. Fields: opcode (6) | rs (5) | rt (5) | immediate (16). Think of it as the format whenever a constant or a memory offset is involved.

J-type (jump type)

An instruction format for unconditional jumps. Fields: opcode (6) | address (26). Only two common instructions use this: j and jal.

Funct (function code)

The last 6 bits (bits 5 to 0) of an R-type instruction. Since all R-type instructions share opcode 000000, the funct field distinguishes between them (e.g. add = 0x20, sub = 0x22, or = 0x25).

rs (source register)

Bits 25 to 21. The first source register in R-type and I-type instructions.

rt (second source or target register)

Bits 20 to 16. In R-type instructions, rt is the second source operand. In I-type instructions, rt is often the destination.

rd (destination register)

Bits 15 to 11. Used only in R-type instructions as the destination register.

shamt (shift amount)

Bits 10 to 6 in R-type instructions. Used by shift instructions (sll, srl) to specify how many bit positions to shift. For non-shift R-type instructions, this field is 00000.

Immediate

A 16-bit constant embedded in I-type instructions (bits 15 to 0). It can be sign-extended (for arithmetic, loads, stores, branches) or zero-extended (for logical operations like ori, andi).

Pseudo-instruction

An assembly instruction that does not correspond directly to a single machine instruction. The assembler translates it into one or more real instructions. Examples: li (load immediate), la (load address), move.

Assembler directive

A command in the assembly source that tells the assembler how to set up data or code, rather than producing a machine instruction. Examples: .data, .text, .word, .asciiz. In simple terms, directives are instructions for the assembler, not for the CPU.


Core Content

MIPS Register Conventions

Name

Number

Use

Preserved across a call?

$zero

0

Constant value 0

N/A

$at

1

Assembler temporary

No

$v0-$v1

2-3

Function return values

No

$a0-$a3

4-7

Function arguments

No

$t0-$t7

8-15

Temporaries

No

$s0-$s7

16-23

Saved temporaries

Yes

$t8-$t9

24-25

Temporaries

No

$sp

29

Stack pointer

Yes

$ra

31

Return address

Yes

Registers $s0 through $s7 must be saved and restored by any function that modifies them (callee-saved). Registers $t0 through $t9 can be freely overwritten by a called function (caller-saved, if you need them after a call).

R-Type Format (Bits 31 to 0)

| opcode (6) | rs (5) | rt (5) | rd (5) | shamt (5) | funct (6) |
|  31---26    | 25--21 | 20--16 | 15--11 |  10---6   |   5---0   |
  • Opcode is always 000000 for R-type.

  • rd is the destination. In assembly: add rd, rs, rt.

  • The order in the machine code (rs, rt, rd) differs from the assembly order (rd, rs, rt). This catches students out regularly.

  • Common R-type instructions: add (funct 0x20), sub (0x22), and (0x24), or (0x25), slt (0x2a), sll (0x00), srl (0x02), jr (0x08).

I-Type Format

| opcode (6) | rs (5) | rt (5) | immediate (16) |
|  31---26    | 25--21 | 20--16 |     15---0      |
  • rt is typically the destination for arithmetic I-type instructions (addi, ori, andi, slti).

  • For loads (lw, lb): rt is the destination register, rs is the base register, immediate is the offset.

  • For stores (sw, sb): rt is the source of data to store, rs is the base register.

  • For branches (beq, bne): rs and rt are compared; the immediate is the branch offset in words.

  • Common I-type opcodes: addi (0x8), addiu (0x9), andi (0xc), ori (0xd), lw (0x23), sw (0x2b), beq (0x4), bne (0x5), lui (0xf), slti (0xa).

J-Type Format

| opcode (6) | address (26) |
|  31---26    |    25---0    |
  • j (opcode 0x2): PC = top 4 bits of PC concatenated with the 26-bit address shifted left by 2.

  • jal (opcode 0x3): same as j, but also saves PC+8 into $ra (register 31) for subroutine return.

Hex to Binary to Instruction (Decoding)

To decode a hex machine code value:

  • Convert the hex to 32-bit binary.

  • Read the first 6 bits as the opcode.

  • If the opcode is 000000, it is R-type: read rs, rt, rd, shamt, funct.

  • Otherwise, check the opcode against the reference sheet. If it matches an I-type opcode, read rs, rt, immediate. If it is 0x2 or 0x3, it is J-type.

  • Look up the register numbers to get register names.

Instruction to Machine Code (Encoding)

To encode an assembly instruction:

  • Identify the instruction type (R, I, or J) from the reference sheet.

  • Look up the opcode (and funct, for R-type).

  • Convert each register name to its 5-bit number.

  • Assemble the fields in the correct order for that format.

  • Convert the 32-bit binary string to hex (group into 4-bit nibbles).

Instructions vs. Pseudo-Instructions vs. Assembler Directives

  • An instruction maps directly to one machine code word. Examples: add, sub, lw, beq.

  • A pseudo-instruction is a convenience provided by the assembler. It translates to one or more real instructions. Example: li \$t0, 0x12345678 becomes lui \$at, 0x1234 followed by ori \$t0, \$at, 0x5678.

  • An assembler directive does not produce machine code at all. It tells the assembler how to lay out data or organise sections. Example: .data, .word 5, .text.


Worked Examples

Decoding 0x012b8022

Step 1: Hex to binary.

0x012b8022 = 0000 0001 0010 1011 1000 0000 0010 0010

Step 2: Read the opcode (bits 31-26).

000000 = R-type.

Step 3: Extract the remaining fields.

  • rs (bits 25-21): 00001 = register 1 = $at

  • rt (bits 20-16): 01011 = register 11 = $t3

  • rd (bits 15-11): 10000 = register 16 = $s0

  • shamt (bits 10-6): 00000

  • funct (bits 5-0): 100010 = 0x22 = sub

Step 4: Write the assembly instruction.

sub \$s0, \$at, \$t3

Encoding or \$s0, \$t2, \$t5

Step 1: Identify the format.

or is R-type. Opcode = 000000. Funct = 0x25 = 100101.

Step 2: Look up register numbers.

  • $s0 = 16 (rd), $t2 = 10 (rs), $t5 = 13 (rt).

Step 3: Assemble the fields.

  • opcode: 000000

  • rs: 01010 (10)

  • rt: 01101 (13)

  • rd: 10000 (16)

  • shamt: 00000

  • funct: 100101

Full binary: 000000 01010 01101 10000 00000 100101

Step 4: Convert to hex.

Group into nibbles: 0000 0001 0100 1101 1000 0000 0010 0101 = 0x014D8025


Common Misconceptions

  • Students mix up the field order between assembly and machine code. In assembly you write add rd, rs, rt, but in the binary encoding the fields are ordered opcode, rs, rt, rd. The destination register changes position.

  • Students forget that R-type instructions all have opcode 000000. If you see a non-zero opcode and start trying to read a funct field, you have the wrong format.

  • Students confuse pseudo-instructions with real instructions on the exam. If a question asks "is this an instruction, a pseudo-instruction, or a directive?" remember that pseudo-instructions (like li, la, move) are not in the machine instruction reference table.

  • Students sometimes think shamt is always 0. It is 0 for most R-type instructions, but shift instructions (sll, srl) use it to specify the number of positions to shift.


Why It Matters / Exam Flags

⚠️ Two of the 7 short-answer questions directly test encoding and decoding: converting hex machine code to a MIPS instruction, and converting a MIPS instruction to binary and hex.

⚠️ Multiple-choice questions will ask about destination vs. source registers by instruction type (R, I, J). Know that rd is the destination for R-type, rt for I-type.

⚠️ Know the distinction between instructions, pseudo-instructions, and assembler directives. This is a direct exam topic.

⚠️ The reference sheets (instruction table and register table) are provided on the exam. Use them. Do not try to memorise every opcode and funct code, but do become fast at looking them up.


Quick Self-Test

  1. True or False: The opcode for all R-type instructions is 000000.
    Answer: True. The funct field distinguishes between different R-type operations.

  1. Fill in the blank: In an R-type instruction, the destination register is encoded in the ______ field (bits 15-11).
    Answer: rd.

  1. True or False: The instruction li (load immediate) is a real MIPS machine instruction.
    Answer: False. It is a pseudo-instruction that the assembler expands into lui and ori.

  1. How many bits wide is the immediate field in an I-type instruction?
    Answer: 16 bits.

  1. True or False: The j instruction uses the I-type format.
    Answer: False. It uses the J-type format (opcode + 26-bit address).


Practice Q&A

Q: What MIPS instruction does the machine code 0x012b8022 represent?

A: sub $s0, $at, $t3. (See worked example above for the full derivation.)

Q: Encode the instruction or \$s0, \$t2, \$t5 as a 32-bit hex value.

A: 0x014D8025. (See worked example above.)

Q: Is move \$t0, \$t1 a real instruction, a pseudo-instruction, or an assembler directive?

A: A pseudo-instruction. The assembler translates it into something like add \$t0, \$zero, \$t1.

Q: Is .word 42 a real instruction, a pseudo-instruction, or an assembler directive?

A: An assembler directive. It tells the assembler to place the value 42 in memory at the current location.

Q: In the machine code for addi \$t0, \$s1, -5, which field holds $t0 and which holds $s1?

A: $s1 (register 17) goes in the rs field (bits 25-21). $t0 (register 8) goes in the rt field (bits 20-16). For I-type arithmetic, rt is the destination, rs is the source.


Related Terms / Search Tags

MIPS instruction format, R-type, I-type, J-type, opcode, funct, function code, rs rt rd, shamt, shift amount, immediate field, register file, machine code encoding, hex to MIPS, MIPS to binary, pseudo-instruction, assembler directive, .data .text .word, register convention, callee-saved, caller-saved, $s registers, $t registers, $ra, $sp, MIPS32, instruction set architecture, ISA