Day 14
I. Last Time:
Hw #4 - Due Next Time
A. Basic Structure/Syntax of an assembler program:
1. Comments: # to end of line (like // in C++)
2. Commands: 1 per line
3. Directives:
Special "notices" to the assembler.
Begin with a period (.)
4. Case: case sensetive to commands
B. Labels.
A label is a special part of an ASM program that is really
a pointer into memory. I.e. it indicates where something
special is.
We'll use labels for both data and instructions.
Data: Label will indicate where a particular variable/
storage area is located.
Instructions:
Label will indicate where a particualar set of
instructions begins.
Like labels in C/C++ character name
using normal identifier conventions, followed
by a colon. (Ex: default: )
C. Immeadiate Instructions:
I-Format instructions are "I"mmeadiate because
one of the pieces of data needed by the instruction
is actually IN the instruction.
(Immeadiately available)
This also allows us to work with "constants":
int a;
a=0; add $t0,$0,$0
a++; addi $t0,$t0,1 # constant 1
D. Branching and Control: beq,bne
Normally, we just do one instruction followed
by another, but occasionally we want to make a
"decision" to do something else - going someplace
else is called branching.
(Branching off from our normal path)
MIPS basically has 2 branching insts.
1. We can branch when 2 things are equal: beq
2. We can branch when 2 things are NOT equal: bne
These are I-format insts...
Q. What goes in the I-Data field?
Answer: "displacement"
Jumping oddities
a. Pre-conditions: Jump to AVOID things
b. Post-Conditions: Jump to do things again
II. New Stuff:
A. Branching and decisions continued:
2. Performing Comparison - Often we want to compare two
values and jump, so we need another instruction(s)
to perform the comparison, and the beq/bne insts
to do the jump.
Trick Question: li $zero,100, add $s0,$0,$0. s0?
We'll also use/abuse register 0, which ALWAYS
has a value of 0 - This is why. It's very usefull in
comparisons.
slt/sltu - Store Less Than and Store Less Than Unsigned
If rs<rt, rd=1, else rd=0
This instruction stores the "truth value" of the expresion
rs<rt.
We can then use this value with beq/bne and $zero to
perform all comparions: <,>,<=,>=
Example:
if(s0>s1){...} after_if:
When do we want to SKIP the block? if S0<=S1
slt possibilities:
slt t0,s0,s1 if t0=1 then s0<s1 (s1>=s0)
if t0=0 then s0>=s1 (s1<=s0)
slt t0,s1,s0 if t0=1 then s0>s1 (s1<s0)
if t0=0 then s0<=s1 (s1>=s0)
(== and != are just done with beq/bne)
So, we want s1,s0 since it's the only way to do
a s0<=s1.
Which branch do we want?
The only thing we can compare to is 0.
beq $t0,$0,after_if
Remember: slt for signed, sltu for unsigned.
(beq/bne work for either signed or unsigned)
3. Real Stuff: Using Pseudo-Ops
As ASM programmers we usually utilize the pseudo-ops
to make the program readable. There are a very rich
variety os pseudo-ops for branching in MIPS,
beqz,bge,bgeu,bgt,bgtu,ble,bleu,blt,bltu,bnez
Psuedo-Ops are converted by the assembler.
The $at register is reserved for this purpose.
Test Type Question: What real instructions does
the instrcution "ble $s0,$s1, after" convert to and what c
construct is it most similiar to:
First think of possibilities:
slt $at,$s1,$s0
if at=1 -> s1<s0 / s0>s1
if at=0 -> s1>=s0 / s0<=s1
We want to branch on less than
slt $at,$s1,$s0
beq $at,$0 after
after:
The closest if statement is:
if(s0>s1)
{...}
after:
ble s0,s1,after_if
C. Other handy pseudo-ops:
move $t0,$t1 # Copy t0=t1
li $t0,1 # Load immediate: t0=1
USE Pseudo-ops: They make the meaning of the
program clearer.
Ex: add $t0,$0,10 vs. li $t0,10
D. jumping:
Relative - a distance (and direction) to go
Absolute - The REAL address
beq/bne - A relative jump. The i-data tells how
many bytes the intended destination is
from the current location.
j - An absolute jump. Gives a specific address
to jump to.
J-Format:
6-bits 26-Bits
op Target Address
Instructions are ALWAYS word aligned - so we know the
last 2 bits will always be 0. (Mult by 4 in binary)
Since we know this, we never store them - the 26 bits
we store are bits 27-2.
(Bits 28-31 come from the current address - so the
jump is only pseudo-absolute)
j 0x1414
op=2=00 0010b
Ta = 0001 0100 0001 0100b =
(drop 2 lowest bits) 0001 0100 0001 01b
Append to 26 bits:
0000 1000 0000 0000 0000 0101 0000 0101b
=0x08000505
If we use the assembler, it just uses labels and
computes the correct number for us - saves us a lot
of time and trouble. So we don't have to worry about
these details soo much.
Any change to the program (insert or delete an inst)
will prob. require that these addresses be re-computed.
Virtual Memory is usually utilized to make a program
"re-locatable"
E. How does a program do IO/talk to hardware/get memory? OS!
How does the computer contact the OS?
In Many os's through syscalls (There are other mechanisms
though like jump gates)
Syscalls - How SPIM simulates an OS for IO and Mem alloc
1. Exceptions, Interrupts, and dealing with the un-expected
External Problem/Request - an INTERRUPT
I.e. an external device has some data ready for the CPU
or user software needs something from the OS
Internal - an EXCEPTION
I.e. a bad inst., a bad address - an ERROR
MIPS - Refers to EVERYTHING as an exception.
Uses a special co-processor (co-pro 0) to deal with
What happens during an interrupt - Control is transfered
to a special set of instructions called an Interrupt handler.
Tricky to write, because they must be bullet proof.
We'll be using syscalls for IO, mem allocation, and
program termination.
2. How syscalls work:
See Page A-49
1. Pick the Function to be performed via v0
2. Set up any "arguments" needed via a0,a1,and f12
(a0 and a1 - "Argument" registers. F12 will be used later
3. Perform syscall - I.e. Tell the OS we're ready for it
4. Collect/deal with any results.
(Ex: integers are returned in v0 - we may need to move
this results elsewhere so we can get another int)
3. A simple syscall:
.data
mesg_pmt: .asciiz "Hello World!!!\n"
.text
main:
li $v0,4
la $a0,mesg_pmt
syscall
li $v0,10
syscall
Misc:
main - A Label telling of the ADDRESS that the
OS should start executing our program.
mesg_pmt - An address of initialized data in the
data segment. In this case our message.
li - Load an immediate value. Pseudo-op for ori.
la - Load an Address. Pseudo-of for ori and lui.
Both of these are pseudo ops, and they both do the
same thing! - More on this later.
syscall - Generates a software interrupt/exception.
the OS looks at an exception code to deal
with and performs function specified in v0
with args specified by a0,a1, and f12.
Then returns to caller.
4. What WE use syscalls for:
ALL IO - to screen only.
print/read int,string,float
Terminate program
allocate memory (sbrk)
III. Next Time:
A. Continue with ASM
B. MIPS memory segmentation
C. Using SPIM