You are on page 1of 47

MIPS Intro / Decisions

CS270 Unit 3
Max Luttrell, Spring 2017
MIPS
• Microprocessor without Interlocking Pipe Stages

• successful chip, came out in the 1990’s

• helped settle CISC/RISC debate

• popular in embedded market

• now owned by Imagination Technologies


MIPS features
• instructions are all uniform length (ours are 32
bits)

• large number of 32-bit registers

• efficient procedure calling convention

• straightforward to write compilers for MIPS


(regularity/large # registers)
arithmetic instructions
• MIPS arithmetic instructions have exactly three
"variables" -- one destination, and two sources

add a, b, c # put b+c in a

# a = b + c + d + e
add a, b, c # put b+c in a
add a, a, d # put b+c+d in a
add a, a, e # put b+c+d+e in a
example
• let's say we have a,b,c,d,e "variables" declared
in a C program. What is the equivalent
assembly for this?

a = b + c;
d = a - e;

add a, b, c # put b+c in a


sub d, a, e # put a-e in d
another example
• let's say we have f,g,h,i,j "variables" declared in
a C program. What is the equivalent assembly
for this?

f = (g+h) - (i+j);

add temp0, g, h # put g+h in temp0


add temp1, i, j # put i+j in temp1
sub f, temp0, temp1 # put temp0-temp1 in f
# note temp0 is now g+h; temp1 is i+j
registers
• Simple Machine: must use the accumulator
register for addition and subtraction

• MIPS: 32 general purpose registers available for


arithmetic and other operations

• we typically use a subset of these for variables


and temporary storage (and other things...)

• each register is 32 bits (one word)


registers

register
register type # registers
name
$s0, $s1,
variable 8 ..., $s7
$t0, $t1,
temporary 10 ..., $t9

argument 4 $a0-$a3

zero 1 $zero

...
register numbers
arithmetic with registers
• let's say we have f,g,h,i,j variables declared in a
C program, assigned to registers $s0, $s1, $s2,
$s3, and $s4 respectively. What is the
equivalent MIPS assembly for this?

f = (g+h) - (i+j);

add $t0, $s1, $s2 # put g+h in $t0


add $t1, $s3, $s4 # put i+j in $t1
sub $s0, $t0, $t1 # put $t0-$t1 in f
# note $t0 is now g+h; $t1 is i+j
using memory
• a C++/java program can contain simple data, arrays,
structures, objects in memory

• to do operations on variables, we need to load memory


to registers and write registers to memory - lw and sw
instructions

• memory is byte addressed

• words are aligned in memory

• address of words must be multiple of 4


memory example 1
• let's say we have g in $s1, h in $s2, and base
address of array A in $s3. For this C code:

g = h + A[6];

• we get the following MIPS code:

lw $t0, 24($s3) # load A[6] to $t0


add $s1, $s2, $t0

offset base
memory example 2
• let's say we have h in $s2, and base address of
array A in $s3. For this C code, what is the MIPS
code?

A[12] = h + A[6];

lw $t0, 24($s3) # load A[6] to $t0


add $t0, $s2, $t0 # $t0 = h+A[6]
sw $t0, 48($s3) # store result at A[12]
spilling
• compiler decides what variables get stored in
what registers

• easy if not many variables

• if too many variables to fit in registers, must spill


less-frequently used variables to memory
immediate operands
• in some arithmetic instructions, you can specify
a constant as your second source

# add 4 to $s3
addi $s3, $s3, 4

# subtract 1 from $s3


addi $s3, $s3, -1
zero
• register $zero is hard wired to zero, i.e. it is
always zero

• nice for common operations, e.g. move values


between registers

# move $s1 to $t1


add $t1, $s1, $zero
MIPS assembly
file overview
name description example

MIPS instruction -
instruction lw $t0, X
operation and operands
# load $t0 with
comment descriptive text - follows # # our data at X

reference to data or
label Result:
instruction - followed by :
assembler special instructions to .text
directive assembler - begin with .
MIPS assembler directives
name description

change to "instruction section" --


.text
afterwards, instructions should appear
change to "data section" -- afterwards,
.data
data statements should appear

.word a,b,c create successive data words (32 bit)

.byte a,b,c create successive data bytes (8 bit)

.space n reserve n bytes of empty space

force alignment of next memory


.align 2
locations on a word boundary
and more...
simple MIPS program
• creates a single labeled data word labeled x
and initializes it to zero. Then it contains a single
instruction that loads that data word into register
t0.

• program begins at the __start label (two


underscores). later we will start at main().
.data
x: .word 0

.text
__start:
lw $t0, x
MIPS instruction formats
• MIPS has three types of instruction formats:

• register type - R-type (e.g. add)

• immediate type - I-type (e.g. addi)

• jump type - J-type (e.g. j)


MIPS R-type instructions
field op rs rt rd shamt funct
# bits 6 5 5 5 5 6

field meaning

op operation code (opcode)

rs first source register number

rt second source register number

rd destination register number

shamt shift amount

funct function code (extends opcode)


register numbers
MIPS R-type encoding
field op rs rt rd shamt funct
# bits 6 5 5 5 5 6

add $t0, $s1, $s2

add $s1 $s2 $t0 0 add

0 17 18 8 0 32

000000 10001 10010 01000 00000 100000

00000010001100100100000000100000binary =
0x02324020
MIPS I-type instructions
field op rs rt constant or address
# bits 6 5 5 16

field meaning

op operation code (opcode)

rs source register number

rt destination register number

constant constant or address

# load A[6] to $t0 # $s4 = $s3 + 4


lw $t0, 24($s3) addi $s4, $s3, 4
bitwise operations
• MIPS supports multiple bitwise operations

operation C/C++ Java MIPS

shift left << << sll

shift right >> >>> srl

bitwise AND & & and, andi

bitwise OR | | or, ori

bitwise NOT ~ ~ nor


bit shifting
• moving bits to the left and right is called bit
shifting

• example: unsigned byte representing 25 = 32

00100000

• shifted left one • shifted right two


bit position: bit positions:
shift left: *2
01000000 00001000 shift right: /2

64decimal 8decimal
logical vs. arithmetic
bit shifting
• previous slide was logical bit shifting. this works
for unsigned values:
1100 logical shift right 1 bit 0110
12dec 6dec
• let's say we right shift a signed value -- doesn't
work!
1100 logical shift right 1 bit 0110
-4dec 6dec
• for signed values we need to use arithmetic bit
shifting (preserve and shift over sign bit):
1100 arithmetic shift right 1 bit 1110
-4dec -2dec
shift operations
field op rs rt rd shamt funct
# bits 6 5 5 5 5 6

• shamt -- how many positions to shift

• shift left logical - sll

• shifts left and fills with 0 bits


i
• note: sll by i bits multiplies by 2

• shift right logical - srl

• shifts right and fills with 0 bits

• note: srl by i bits divides by 2i (sra is arithmetic)


AND operations
• useful to mask bits in a word

• selects some bits, clear others to zero

and $t0, $t1, $t2


OR operations
• useful to set some bits to 1

• set some bits to 1, others are unchanged

or $t0, $t1, $t2


NOT operations
• can use NOR to invert bits

• a NOR b means NOT (a OR b)

nor $t0, $t1, $zero


decisions
• high level language: if, goto

• MIPS branches

• beq reg1, reg2, L1

• if reg1 == reg2, go to instruction labeled L1

• bne reg1, reg2, L1

• if reg1 != reg2, go to instruction labeled L1

• j L1

• go to instruction labeled L1
decision example
• let's say we have the f,g,h,i,j variables assigned to
registers $s0 through $s4 for the C code below. What
is the equivalent assembly for this?

if (i==j)
f = g + h;
else
f = g - h;

bne $s3, $s4, Else
add $s0, $s1, $s2
j Exit
Else: sub $s0, $s1, $s2
Exit: …
loops
• let's say we have the i and k variables in $s3 and
$s5, and the base of array save is in $s6. What
is the equivalent assembly for this?

while (save[i] == k)
i += 1;

pseudocode:
1. put address of save[i] in $t1
- note: it is i*4 + s6
2. load save[i] to $t0
3. if save[i]!=k, jump out of loop
4. increment i
5. jump back to step 1
loops
i and k variables in $s3 and $s5, base of save in $s6.
pseudocode:
1. get the address of save[i]
- note: it is i*4 + s6
2. load save[i] to $t0
3. if save[i]!=k, jump out of loop
4. increment i
5. jump back to step 1

Loop:
sll $t1, $s3, 2 # $t1 = i*4 (shift left 2 is mult by 4)
add $t1, $t1, $s6 # $t1 = address of save[i]
lw $t0, 0($t1) # $t0 = save[i]
bne $t0, $s5, Exit # branch out of loop if save[i]!=k
addi $s3, $s3, 1 # i++
j Loop # go back to top of loop
Exit:
slt - set on less than
• equality testing is useful, but so is testing if a
variable is less than another

• slt instruction - set to 1 on less than

slt $t0, $s3, $s4 # $t0=1 if $s3<$s4; $t0=0 if not

• slti - set on less than immediate

slti $t0, $s2, 10 # $t0=1 if $s2<10; $t0=0 if not


relative conditions
• MIPS compilers use slt, slti, beq, bne for all conditions:

• is equal ==

• not equal !=

• less than < #example:


#if ($s1 < $s2)
# goto L
• less than or equal <= slt $t0, $s1, $s2
bne $t0, $zero, L
• greater than >

• greater than or equal >=


addressing
field op rs rt constant or address
# bits 6 5 5 16
• recall we only have 16 bits for our constants in I-
type instructions

• to load a larger constant, we need to do it in


steps, using the lui instruction - load upper
immediate:

• loads 16-bit constant to upper bits of register

• clears lower 16 bits to zero


lui
• to load the following 32 bit constant into $s0:

0000 0000 0011 1101 0000 1001 0000 0000

$s0
lui $s0, 61 0000 0000 0011 1101 0000 0000 0000 0000

ori $s0,$s0,2304 0000 0000 0011 1101 0000 1001 0000 0000

Note: 61decimal = 0000 0000 0011 1101binary


Note: 2304decimal = 0000 1001 0000 0000binary
conditional branch
addressing
• conditional branch instruction contains opcode,
two registers, and the target address

• we have 16 bits for target address

• if address is absolute, this would mean we have


216 = 65536 addresses available
PC-relative addressing
• In SPEC benchmarks, half of all conditional branches
go to locations less than 16 instructions away

• idea: use PC-relative addressing for conditional


branches

• Program counter = Program counter + Branch address

• note: since all instructions are 32-bit (4 byte), PC-


relative addressing refers to # of words to next
instruction
jump addressing
• jump (j and jal) targets can be anywhere
in .text area

• we have 26 bits available for the address. we


again restrict addressing to words, meaning we
can jump to 28-bit byte addresses

• use PC(31:28) for upper 4 bits

Target address = PC(31:28) : (address × 4)


example
• let's look at encoding for our previous loop
example; assume Loop is at location 80000decimal

Don't forget -- PC automatically incremented


1 word (4 bytes) after every instruction!
branching far away
• let's say we have the following branch
statement, but L1 is too far away to work in our
16-bit word (18-bit byte) addressing scheme:

beq $s0, $s1, L1

bne $s0, $s1, L2


j L1
L2:

Exercise 3A
start MARS. make sure that settings->exception handler is unchecked to get
your program to begin at __start

• the file first.s on hills in exercises/intromips is your starting point for this
exercise. you can copy it to your current directory using scp (replace login with
your hills username)

• scp login@hills.ccsf.edu:/pub/cs/mluttrel/cs270/exercises/intromips/first.s .

• add some MIPS instructions to do the following C++ statement:

result = a1+b1+c1

• once you have your instructions, do run->assemble to assemble your program.


you'll notice some of your instructions have been translated into two MIPS
instructions. that's normal.

• check out the registers on the right, and the data segment. can you tell where
the data from first.s is stored in this data window?

• now you can use the button to step through your instructions one
instruction at a time. to start over, hit the button. make sure you see that
result gets stored with the correct answer!
Exercise 3B

Exercise 3B
Exercise 3C
• Write a MIPS program which implements the following C code:
result=0;
for (i=Nelems-1; i!=0; i--) {
if (arr[i] < 0) { arr[i] = -arr[i]; result++; }
}

• You can get a starting file from hills by using the following scp
command (all one line; replace uname with your username):

scp uname@hills.ccsf.edu:/pub/cs/mluttrel/cs270/exercises/
decisions/decisions.s .

• Note: I have placed ugly C code with goto's and labels which is
equivalent to the above C code in this file. It should be easier for
you to translate this ugly C code to MIPS assembly than the
more natural C code above.

• Make sure to store result in register $t7, and the starting code
will output it for you

You might also like