Day 13
I. Last Time:
Hw #3 DUE!!
Hw #4 - Due Next Week
A. Memory: lw & sw:
1. Describing Location: Base + Offset
Base in "register" offset is how "far"
lw/sw just move 32-bits: No Type
B. I-Format Instructions -
Immeadiate data - Some Data is included in
the instructions. Data Manipulation and some
control instructions
Format:
6 bits 5 bits 5 bits 16 bits
op code rs rt Immediate data
C. Alignment: MIPS designers designed the machine around
"aligned" words - lw and sw can ONLY access words that
are on an address/index that is a multiple of 4.
Shortcut test: If you're given an address in binary/hex,
just check to see if the last 2 digits are 0s.
Ex: 0xACD487A = ...1010 (Bad)
0xACD487C = ... 1100 (Good)
II. New Stuff:
A. Misc. Working with Bytes: lb & sb can be used to
load and store bytes in the same way that lw & sw
can be used to store words.
Differences: No Word Alignment Constraints
Loads byte into LOWER byte of reg, rest is 0
Stores byte from LOWER byte of reg
Things that won't work: if $s0=0 and $s1=1:
lw $s4,0($s1), lw $s4,1($s1), lw $s4,1($s0), etc.
There are some good reasons for this choice.
(And it typically doesn't really waste much space)
We'll see one advantage of this later in the jump instruction
NOTE: This is only true with WORDS: lw, sw.
(lb, sb don't have any problems)
B. Basic Structure/Syntax of an assembler program:
1. A program in a text File
2. Give Text File to Assembler to convert to Machine Lang. (typ)
In Our case - The simulator we use (SPIM) also acts as an Assembler
1. Comments: # to end of line (like // in C++)
(Don't tell me WHAT you're doing, tell me WHY!)
We don't have "data types" or relevant variable names
in ASM, we even re-use single variables for a lot of
different tasks. Good commenting is absolutely vital!!!
2. Commands:
Simple Instructions, 1 per line
(eol = terminator (like ; in C++))
Each Inst. has a specific format
(Like C++ keywords: add, lw, sw, sub, or, etc.)
3. Directives:
Special "notices" to the assembler.
Begin with a period (.)
(Similiar to #defines in C++)
4. Constants:
Numbers/characters embedded in the program:
Characters: in Quotes: "This is text"
Decimal Numbers: Just the number: 45
Hex Numbers: Preceeded by a 0x Ex: 0x12AC
Labels: Like labels in C/C++ character name
using normal identifier conventions, followed
by a colon. (Ex: default: )
5. Spacing/Indentation - 1 command per line.
Try to make clear.
6. Case: case sensetive to commands
7. Register Names: Registers have both a symbolic and a numeric Name
Numeric name: $<number>
$0 - $zero - Register[0]
$1 - $at - Register[1]
$2 - $v0 - Register[2]
// v1,a0-a3,
$8 - $t0 - Register[8]
$9 - $t1 - Register[9]
...
$15 - $t7 - Register[15]
$16 - $s0 - Register[16]
$17 - $s1 - Register[17]
...
$23 - $s7 - Register[23]
$24 - $t8 - Register[24]
$25 - $t9 - Register[25]
We'll only work with the "s-registers" today
Names established to enforce usage conventions so
different assembly programmers can work together.
We'll discuss these usage conventions next week.
They are established to ensure that modules written
by different programmers will successfully work
together. They are NOT enforced by the hardware but
they WILL be enforced by me.
C. 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: )
D. 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
E. Branching and Control: beq,bne
Branching is used to make decisions in a program:
If statements, Loops, etc.
(It's called "branching" because the program "branches"
off of it's "normal" (sequential) path)
1. MIPS only has TWO instructions for conditional control
(This is an oversimplification - really there are
more, but we'll only need these 2)
beq - Branch on equal:
I-Format
Compare the RS and RT registers. If there are equal
jump of I-Data bytes. I-Data is SIGNED!
bne - Branch on NOT equal
I-Format
Compare the RS and RT registers. If there are NOT
equal jump of I-Data bytes. I-Data is SIGNED!
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: <,>,<=,>=
3. Jumping oddities
a. Pre-conditions: Jump to AVOID things
b. Post-Conditions: Jump to do things again
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)
4. 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
F. 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"
III. Next Time:
C. Continue with ASM