SPIM Assembly Programming

Download Report

Transcript SPIM Assembly Programming

Assembly Language
Working with the CPU
Overview
•
•
•
•
•
•
What is SPIM?
Fetch-Execute Cycle
Declaring “variables”
I/O
Commands
Loops
What is SPIM?
• SPIM is a simulator that runs programs for
the MIPS R2000/R3000 RISC computers
• SPIM is MIPS backwards
• PC-SPIM is the windows version of SPIM
• MIPS
• Assembly files usually end in .a
Why is Assembly Important?
Fetch-Execute Cycle
Text vs Data
• Assembly programs have two sections:
– Text
• Instructions go here
• Larger of the two sections
• Contains the beginning of the program
– Data
• Where the variables are declared
• A limited number of data types in ASM
• Everything is separated by tabs!
Declaring Data
• Done in the .data section
<name>:
str:
str2:
number:
bigNum:
.<type>
.asciiz
.ascii
.byte
.word
<value>
“Hello World\0”
“Hello”
10
10000
The Registers
Note: there are also 16 floating-point registers $f0-$f15
I/O
Load one of these values into $v0 and arguments into registers
$a0…$a3. $v0 is for system calls
Hello World
.text
# instruction segment starts here
.globl __start # tell where to start
__start:
# execution starts here
la $a0, str
# load the address of str into $a0
li $v0, 4
# syscall 4 prints the string whose address is in $a0
# look at chart!
syscall
# call syscall
li $v0, 10
# syscall 10 exit program
syscall
# call syscall
.data
# data segment starts here
str: .asciiz "hello world\n" #define a null terminated string called str
It is very important that you understand when the syscall
is executed, it will look in $a0 for what is to be printed
Commands
add
addi
sub
$r0, $r2, $r3 # r0 = r2 + r3
$t0, $t1, 15 # t0 = t1 + 15 (from instruction)
$r0, $r0, $r3 # r0 = r0 – r3
mul
div
$t0, $t1, $t2 # t0 = t1 * t2
$t0, $t1, $t2 # t0 = t1 / t2
la
li
$a0, str
$t1, 3
# load address of str into $a0
# t1 = 3 (from instruction)
Multiplication/Division
• Because multiplication/division can result in a
larger number, there are two special registers
named lo and hi
# move 5 into $t0
li
$t0, 5
# move 2 into $t1
li
$t1, 2
# mult, putting into lo & hi
mult $t0, $t1
# move from lo into $t3
mflo $t3
.text
.globl __start
# Fahrenheit to Celsius calculator
la $a0, prompt
li $v0, 4
syscall
li $v0, 5
syscall
# print prompt on terminal
mul $t0, $v0, 9
div $t0, $t0, 5
add $t0, $t0, 32
# to convert, multiply by 9,
# divide by 5, then
# add 32
la $a0, ans1
li $v0, 4
syscall
# print string before result
move $a0, $t0
li $v0, 1
syscall
la $a0, endl
li $v0, 4
syscall
li $v0, 10
syscall
# print result
__start:
# read from user
# system call to print
# out a newline
# exit program
prompt:
ans1:
.data
# data segment
.asciiz "Enter temperature (Celsius): "
.asciiz "The temperature in Fahrenheit is: "
endl:
.asciiz "\n"
Control Structures
j
beq
beqz
bne
blt
<addr>
#update PC to be addr
$t0, $t1, <addr> #if t0==t1, go to addr
$t0, <addr>#if t0 == 0, go to addr
$t0, $t1, <addr> #if t0 != t1, go to addr
$t0, $t1, <addr> #if t0 < t1, go to addr
“Mmmm.. blt…” – Homer Simpson
Labels
• Anywhere in our code, we can put a label
• Labels are names in the code
• Keep us from having to know the exact
memory address!
• Labels are followed by a colon
myLabel:
Count to 10
.text
.globl __start
__start:
li
$t0, 0
loop:
add
$t0, 1
move $a0, $t0
li
$v0, 1
syscall
# $t0 will be our counter, starting at 0
# here is our label to jump to later
# $t0 = $t0 + 1
# $a0 = $t0, necessary because $v0 works with $a0
# what kind of syscall? Print int! Go back & look at chart
la
$a0, endl
li
$v0, 4
syscall
# print a return (\n)
bne
# if $t0 != 10, then branch to the loop label
$t0, 10, loop
li $v0, 4
la $a0, str
syscall
.data
endl:
.asciiz
str:
.asciiz
# print “Thank you”
# data section
"\n";
"Thank you!\n"
Reading in Strings
• First, need to open up space for the string
# open up 64 bytes
mySpace:
.space
64
• String goes into $a0, and length into $a1
la $a0, mySpace
li $a1, 64
• Do system call
li $v0, 8
• Now, mySpace is an array of characters!
mySpace
0
1
2
3
4
5
6
H
E
L
L
O
\n
\0
63
………
.text
.globl __start
__start:
la
$a0, gimme
li
$v0, 4
syscall
# print gimme a cookie
li
$v0, 8
la
$a0, mySpace
li
$a1, 64
syscall
# read string $a0 = buffer, $a1 = l
# read into mySpace
# read max of 64
li
li
$t0, 0
$t5, 6
# this is our counter
# number of letter in cookie
lb
lb
bne
addi
bne
$t2, mySpace($t0)
$t3, cookie($t0)
$t2, $t3, __start
$t0, 1
$t0, $t5, loop
# copy char of mySpace into $t2
# copy char of cookie into $t3
# if not equal, jump to start
# $t0 = $t0 + 1
# if $t0 isn't 6, jump back to loop
loop:
end:
la
$a0, rock
li
$v0, 4
syscall
.data
gimme:
rock:
mySpace:
cookie:
.asciiz
.asciiz
.space
.asciiz
# print you rock!
"Gimme a cookie: "
"You rock!\n"
64
"cookie"
For More Information
• http://www.compapp.dcu.ie/~jkellehe/architect
ure/