Download as pdf or txt
Download as pdf or txt
You are on page 1of 44

MIPS Tutorial: General

Think of assembly language as a very low level programming


language.
There are very few instructions.
Many things that you can do in one step in high level languages
you have to do in many steps
Why learn Assembly Language?
It is the language of the machine. Computers dont understand
C or Java directly.
Well see how we can implement assembly language.
It helps you to understand how compilers work

18-347 Fall 2003

Lec.03 - 288

MIPS Tutorial: Registers







The MIPS processor has 32 special variables called registers.


These registers can hold 32 bits (4 Bytes).
Some of the registers have special uses. The registers have the
names $0-$31, they also have other names.
In the next few lectures we will be concerned with the
following registers:

Name
$t0-$t7
$s0-$s7
$t8-$t9

18-347 Fall 2003

Number
8-15
16-23
24-25

Usage
Temporaries
Saved
more temporaries

Lec.03 - 289

MIPS Tutorial: Register usage




When you are writing your assembly language programs, a $


means that there is a register.

While the assembler can often guess what you mean it is


better to write what you mean.

The above instruction could be rewritten as


addi $8,$8,1
If you wrote
add 8,8,1
The assembler would have a hard job of guessing what you
mean.




18-347 Fall 2003

Lec.03 - 290

MIPS Tutorial: 3-operand inst.


Pseudo C code
$s0 = $s5 + $t0
Assembly language:
add $s0,$s5,$t0
Arithmetic instructions have three arguments the first two must
be registers and the last is a register or a small constant (more
later).
Arithmetic instructions, first argument is the destination.
Important: Arithmetic instructions can only have 3 arguments.

18-347 Fall 2003

Lec.03 - 291

MIPS Tutorial: Temp. registers


Pseudo C code
$s0 = $s1 + $s2 + $s4 + 2*$s5
Assembly language:
add $t0,$s1,$s2
add $t0,$s4,$t0
add $t1,$s5,$s5
add $s0,$t0,$t1
The add instruction does not get confused if the destination
register is the same as a source register.

18-347 Fall 2003

Lec.03 - 292

MIPS Tutorial: Immediates






What about constants?


How do we do do things like $t0 = $t0 + 1?
We cant just magic the values into registers we have
to load values in there.

The last operand of an add instruction can be a small


constant (a16bit number). The new form of the
instruction is called addi, the i stands for immediate.
addi $t0,$t0,1


18-347 Fall 2003

Lec.03 - 293

MIPS Tutorial: Immediates





How do we put a value in a register?


The MIPS processor has a special register,number 0,
which is hardwired to be the value 0. No matter what
you do to that register it stays at that value.

This register is called $0 or $zero .

How do I set $s0 to be 34?


add $s0,$zero,34

18-347 Fall 2003

Lec.03 - 294

MIPS Tutorial: Immediates





There is no direct way of loading large constants into a register.


It must be done in two steps.
For example to load the value 0x0fff0123 into the register $s0
we have to do the following:
lui $s0,0xfff0




This places the value 0xfff00000 into theregister $s0.


lui stands for load upper immediate.
add $s0,$s0,0x0123

18-347 Fall 2003

Lec.03 - 295

MIPS Tutorial: Recap Arithmetic







32 registers, each can hold 32 bit integers.


register $0 is fixed at the value 0.
Arithmetic instructions, very limited format, all ways three
arguments.
Destination is the first register.

18-347 Fall 2003

Lec.03 - 296

MIPS Tutorial: Load








To read information from memory you us the, lw, load word


instruction.
Assume $s0 holds the address 0x8000000 then
lw $t0,0($s0)
Will load the contents of memory location 0x8000000 into
$t0 and
lw $t0,4($s0)
will load the contents of memory location 0x8000004 into
$t0.
Format of lw:
lw register,constant(register)
The constant cannot be a register

18-347 Fall 2003

Lec.03 - 297

MIPS Tutorial: Load




How do we load an address into a register? We can


you the same trick as in the previous lecture, but
there is a pseudo instruction:
la $t0,address

There is a reason that you you la rather than li, but I


cant tell you what it is yet.
When you start doing your labs youll start to learn
how to use labels.

18-347 Fall 2003

Lec.03 - 298

MIPS Tutorial: Store




To store a value from a register into a memory


location you use, sw, store word. This instruction has
the same format as lw.
la
li
sw
sw

$s0,0x8000000
$t0,10
$t0,0($s0)
$t0,4($s0)

This puts the value 10 into locations 0x8000000 and


0x8000004.

18-347 Fall 2003

Lec.03 - 299

MIPS Tutorial: Addressing Modes




To access the ith element of an integer array you


need to access the memory address





Base Address + 4 i

Sometimes, especially when you are dealing strings


you want to read and write bytes.
The MIPS processor has two instructions lb and sb
which read and write bytes, these have the same
format as lw and sw.

18-347 Fall 2003

Lec.03 - 300

Recap Load/Store







la to load an address into a register.


Remember there is a distinction between the address
and the value stored at that address. (Pointers and
values).
lw load a value into a register from memory, sw store
a value and sw from a register to memory.
Integer arrays, multiply by 4.
Strings and byte arrays, use lb and sb.

18-347 Fall 2003

Lec.03 - 301

MIPS Tutorial: Control Flow


Labels
Making Decisions beq and bne
Jumps.
Some example programs
Programs and Data live in Memory.
The processor does not understand strings of characters such
as add for instructions.
Each instruction is a unique number. For example the in
instruction
lw $4, 0($29)
has the code 0x8fa40000.
 Each instruction has an address.

18-347 Fall 2003

Lec.03 - 302

MIPS Tutorial


Programs and data are in the same memory. The processor


just fetches numbers from memory executes instructions.
Almost every combination of bits is an instruction. Thus you
could ask the machine to execute a sound file with
unpredictable consequences.

Also, the machine has no way of knowing if a value in memory


is data or an instruction. So if you do a lw or a sw you better
know what your reading or writing.

All this has a positive side, you can write programs that write
other programs (Can you think of any?).

Your assembly language programs will fail in very strange


ways, you better get used to understanding the code you
write.

18-347 Fall 2003

Lec.03 - 303

MIPS Tutorial: PC addresses






Every instruction has an address.


Sometimes you need to know the address of an instruction.
Every instruction takes up exactly 4 bytes of memory (on the
MIPS), it is possible in theory to work out the address of any
instruction if you know the address of the first instruction.

Working out the address of an instruction can be tedious,


luckily
there is a program called an assembler which works this out.

18-347 Fall 2003

Lec.03 - 304

MIPS Tutorial
.data
n1:
.word 10
.text
.globl main
main:
la $t0,n1
lw $s0,0($t0)
addi $s0,$s0,1
sw $s0,0($t0)
jr $31
 main is the address of the first instruction. n1 is the address of
a piece of data.

18-347 Fall 2003

Lec.03 - 305

MIPS Tutorial: BEQ, BNE


All the programs we have looked at so far have been
linear. We need a way of doing different things
depending on the values of registers.
 The MIPS processor provides two instructions for
making decisions:
beq Branch if Equal
bne Branch if not equal
 General format:
beq $register1,$register2,Label


18-347 Fall 2003

Lec.03 - 306

MIPS Tutorial: BEQ, BNE


beq $register1,$register2,Label
If $regisiter1 is equal to $regisiter2 then goto Label
otherwise execute the next instruction.
bne $register1,$register2,Label
If $regisiter1 is not equal to $regisiter2 then goto Label
otherwise execute the next instruction.

18-347 Fall 2003

Lec.03 - 307

MIPS Tutorial: If then


Pseudo C code:
if $s1 == $s2 then $s3 = 0 ;
Assembly language:

skip:

18-347 Fall 2003

bne $s1,$s2,skip
add $s3,$0,$0
Next Instruction

Lec.03 - 308

MIPS Tutorial: if then else


Pseudo C code:
if $s1 = $s2 then $s3 = 0 else $s3 = $s3 + 1 ;
Assembly code:

set_zero:
skip2:


beq $s1,$s2,set_zero
addi $s3,$s3,1
j skip2
add $s3,$0,$0
Next Instruction

Jump instruction. This is like an unconditional branch : make


the next instruction the label.

18-347 Fall 2003

Lec.03 - 309

MIPS Tutorial
There is often more than one way of writing the same piece of
code.
For example:

skip:

bne $s1,$s2,skip
add $s3,$0,$0
Next Instruction

Can also be written as:

settozero:
skip:

18-347 Fall 2003

beq $s1,$s2,settozero
j skip
add $s3,$0,$0
Next Instruction

Lec.03 - 310

MIPS Tutorial: Loops


Assume that the base of the integer array A is stored in $s0.
loop:

exit:

addi $t0,$0,0
addi $t1,$0,10
beq $t0,$t1,exit
add $t2,$t0,$t0
add $t2,$t2,$t2 # $t2 = $t0*4
add $t2,$s0,$t2 # $t2 = address of A[$t0]
sw $0,0($t2)
addi $t0,$t0,1
j loop

Pseudo C code
for($t0 = 0; $t0 != 10 ; $t0 = $t0 +1 ) {
A[$t0] = 0
}
18-347 Fall 2003

Lec.03 - 311

MIPS Tutorial: Loops


Look at the loop on the previous slide. How can we make it more
efficient?
We dont have to load 10 in $t1 each time around the loop
because $t1 does not change (this is called a loop invariant).
 We can do the test to exit the loop at the end of the loop,
because we know the loop executes at least once.
 Instead of multiplying by 4 each time around the loop We can
add 4 to $t0 each time and exit when $t0 is equal to 40.
Exercise: rewrite the above code.

18-347 Fall 2003

Lec.03 - 312

MIPS Tutorial: SLT





So far we have only compare if registers are equal or different.


The MIPS provides no branch on less than.

Instead there is the slt instruction.

General format
slt $Rdest,$Rsrc1,$RSrc2

Set Register Rdest to 1 if register Rsrc is less than Rsrc2, set to


zerootherwise.

18-347 Fall 2003

Lec.03 - 313

MIPS Tutorial


Pseudo C code:
if $s1 < $s2 then $s3 = 0

Assembly:

slt $t0,$s1,$s2
beq $t0,$zero,skip
add $s3,$zero,$zero
skip:

18-347 Fall 2003

Lec.03 - 314

MIPS Tutorial: functions




As in high level languages , when programming in


assembly language you should split up your program
into smaller functions, that you can reuse.
One of the key ideas with functions is that you can call
them from anywhere and return back to where you
called the function from
The MIPS processor has two instructions that enable
you to call functions, jr and jal.

18-347 Fall 2003

Lec.03 - 315

MIPS Tutorial: functions





Jump and link.


jal label
Copies the address of the next instruction into the
register $ra (register 31) and then jumps to the
address label.
jr $register jumps to the address in $register most
common use
jr $ra

18-347 Fall 2003

Lec.03 - 316

MIPS Tutorial: functions


.data
str: .asciiz "Hello World!.\n"
.text
.globl main #necessary for the assembler
main: jal message
jal message
li $v0,10
syscall #exit the program gracefully
message: la $a0,str
li $v0,4
syscall #Magic to printhings on the screen.
jr $ra

18-347 Fall 2003

Lec.03 - 317

MIPS Tutorial: functions







There are many way of passing values to functions, but there is a


convention that most programs on the MIPS follow.
$a0-$a3 (registers 4 to 7) arguments 1-4 of a function.
$v0-$v1 (registers 2 and 3) results of a function.

silly:

18-347 Fall 2003

li $a0,10
li $a1,21
li $a3,31
jal silly
#result is is $v0.
li $v0,10
syscall
add $t0,$a0,$a1
sub $v0,$a3,$t0
jr $ra

Lec.03 - 318

MIPS Tutorial: functions


On the previous slide in our function we needed an extra register
to do part of a calculation.
How do we know what registers to use?
 As with function calls there is a convention.
 $s0-$s7 the saved registers, these registers should be
unchanged after a function call.
 $t0-$t9 these are temporaries, are are not necessarily
preserved across function calls.
 So in the previous example it would of been a bad thing to use
$s0 in the function silly.


What happens if we run out of registers? What happens if we


have to use $s0?

18-347 Fall 2003

Lec.03 - 319

MIPS Tutorial: functions


after1:
silly:
after2:
silly2:


jal silly

jal silly2

jr $ra

jr $ra

So we have to save $ra as well!

18-347 Fall 2003

Lec.03 - 320

MIPS Tutorial: STACK




A stack is a data structure, at least two operations:





push put a value on the top of the stack


pop remove an item from the top of the stack.

The important thing about a stack is that it is a LIFO


(Last in First Out) data structure. This is useful for
nested functions.

You store your temporary data by pushing it onto the


stack and restore things by popping things from it

18-347 Fall 2003

Lec.03 - 321

MIPS Tutorial: STACK








The MIPS has no specialized push and pop


instructions (Other processors do).
Instead the stack is implemented using the register
$sp (number 29), lw and sw.
Unless you are writing an operating system the
register $sp points to the top of the stack.
On the MIPS stacks grow downwards.
You have to manipulate the value of the register $sp
and then use store and load.

18-347 Fall 2003

Lec.03 - 322

MIPS Tutorial: STACK




To push the contents of register $s0 onto the stack. Do the


following:
addi $sp,$sp,-4
sw $s0,0($sp)
To pop the top of the stack into register $s0 do the following:
lw $s0,0($sp)
add $sp,$sp,4
Basic rules:



Everything you push onto the stack, you must pop from the stack.
Never touch anything on the stack that does not belong to you.

18-347 Fall 2003

Lec.03 - 323

MIPS Tutorial: STACK

silly:

18-347 Fall 2003

addi $sp,$sp,-4
sw $ra,0($sp)
jal silly2
lw $ra,0($sp)
add $sp,$sp,4
jr $ra

# PUSH
# ra
# POP
# ra

Lec.03 - 324

MIPS Tutorial: STACK


silly:

18-347 Fall 2003

addi $sp,$sp,-4
sw $s0,0($sp)
addi $sp,$sp,-4
sw $ra,0($sp)

jal silly2

lw $ra,0($sp)
add $sp,$sp,4
lw $s0,0($sp)
add $sp,$sp,4
jr $ra

#
#
#
#

PUSH
s0
PUSH
ra

#
#
#
#

POP
ra
POP
s0

Lec.03 - 325

MIPS Tutorial: STACK


silly:

addi $sp,$sp,-8
sw $s0,4($sp)
sw $ra,0($sp)

jal silly2

lw $ra,0($sp)
lw $s0,4($sp)
addi $sp,$sp,8
jr $ra

General rule (applies to all programs youll ever write):




Write the inefficient version once that is correct; then optimize.

18-347 Fall 2003

Lec.03 - 326

MIPS Tutorial: functions




All arguments and all results via the stack

Optimization:



$a0-$a3 (registers 4 to 7) arguments 1-4 of a function.


$v0-$v1 (registers 2 and 3) results of a function

18-347 Fall 2003

Lec.03 - 327

Example


Factorial


N! = N*(N-1)*(N-2)* * 1

Recursive function: a function that calls itself




Can only be implemented on the stack

18-347 Fall 2003

Lec.03 - 328

Example: factorial
result: .space 4 #the place for the result
.text
.globl main
main: addi $sp,$sp,-4 #save the return address.
sw $ra,0($sp)
lw $a0, 5
jal fact
la $t0,result
sw $v0, 0($t0)
lw $ra,0($sp)
addi $sp,$sp,4
jr $ra

18-347 Fall 2003

Lec.03 - 329

Example: factorial
fact:

addi $sp,$sp,-4
sw $ra,0($sp) #push $ra on the stack
#fact of 0 is 1
bne $a0,$zero,not_zero
#Set $v0 to be 1
addi $v0,$zero,1
#Restore $ra from the stack
lw $ra,0($sp) #Read $ra from the stack
addi $sp,$sp,4 #restore stack pointer.
jr $ra

18-347 Fall 2003

Lec.03 - 330

Example: factorial
not_zero:
addi $sp,$sp,-4
sw $a0,0($sp) #push n on the stack ($a0=n)
#So call fact with our new parameter
addi $a0,$a0,-1
jal fact # $v0=fact(n-1)
lw $t0,0($sp) #restore n from the stack.
addi $sp,$sp,4
mul $v0,$v0,$t0 #$v0 = fact(n-1)($v0)*n($t0)
#Restore the stack for $ra
lw $ra,0($sp)
addi $sp,$sp,4
jr $ra

18-347 Fall 2003

Lec.03 - 331

You might also like