load and store

Introduction

The MIPS ISA is a load-store architecture. This means that the only operations that interact with memory are load and store.

CISC ISAs often have other kinds of instructions that interact with memory. For example, there may be an instruction that adds the contents of a register to the contents at a memory address and store that in a register.

These kinds of instructions do not appear in MIPS ISA, nor in most RISC ISAs.

Example and Semantics

We'll look at a few versions of load and store. Notice that there's no sbu (store byte unsigned). This is unnecessary since a single byte is being written to memory (thus, there's no sign extension to 32 bits, as there is when reading a byte into a 32-bit register).

lw  $rt, offset($rs)
lb  $rt, offset($rs)
lbu $rt, offset($rs)
sw  $rt, offset($rs)
sb  $rt, offset($rs)
The offset is a 16-bit 2C value.

We'll consider the semantics of lw, and then explain the semantics of the other instructions.

 Addr <- R[s] + (IR15)16::IR15-0
 R[t] <- M4[ Addr ]

The address is computed by adding the contents of register s to the sign-extended offset (which is an immediate value). This may result in an address that is not word-aligned (i.e., whose binary address does not end in 00). If that happens, a hardware exception occurs.

The four bytes located at memory address starting at addres, Addr, are copied to register t. The CPU fetches the four bytes based on the endianness of the CPU. Thus, the CPU arranges the bytes correctly within the register depending on whether the machine is big or little endian.

For lb, the address is computed the same way as lw, but the address does not have to be word aligned. The semantics of lb are shown below.

 Addr <- R[s] + (IR15)16::IR15-0
 R[t] <- (M1[ Addr ]7)24::M1[ Addr ]
Only one byte is loaded from memory. However, since this must be stored in a 32 bit register, and since the quantity is interpreted as 2C, the fetched byte is sign-extended to 32 bits. This is what (M1[ Addr ]7)24 means (it's the sign bit copied 24 times).

lbu is just like lb except the byte is zero-extended in the register.

sw is similar to lw except the four byte quantity is copied from the register to memory.

 Addr <- R[s] + (IR15)16::IR15-0
 M4[ Addr ] <- R[t]
When the contents of register t is written to memory, it is stored in the endianness of the CPU.

sb is similar to sw. The least significant byte of register t is copied to the address in memory.

 Addr <- R[s] + (IR15)16::IR15-0
 M1[ Addr ] <- R[t]7-0
There are other instructions for loading and storing halfwords, but we'll ignore them.

Machine Code Representation

All of the load/store instructions are I-type since they use a 16-bit 2C immediate value as the offset.

Instruction B31-26 B25-21 B20-16                 B15-0                
  opcode register s register t immediate
lw $rt, <offset>$rs) 100 011 - - offset
lb $rt, <offset>$rs) 100 000 - - offset
lbu $rt, <offset>$rs) 100 100 - - offset
sw $rt, <offset>$rs) 101 011 - - offset
sw $rt, <offset>$rs) 101 100 - - offset

The dashes are 5-bit encoding of the register number in UB. For example, $r7 is encoded as 00111. The offset is represented in 16-bit 2C.

Web Accessibility