Uploaded by Sarah Al-Douqi

6 MIPS Assembly.pdf

advertisement
I
CPCS 214
Cifl
Is
Computer Organization and Architecture
Dr. Laila Nassef
0
Overview of the MIPS Architecture
...
Memory
4 bytes per word
Up to 232 bytes = 230 words
...
EI
U
32 General
Purpose
Registers
Arithmetic &
Logic Unit
$0
$1
$2
$31
AL
U
Execution &
Integer Unit
(Main proc)
Integer
mul/div
H
i
Integer
Multiplier/Divider
L
o
FP
U
FP
Arit
h
F
0
F
1
F
2
Floating
Point Unit
(Coproc 1)
32 Floating-Point
Registers
F31
Floating-Point
Arithmetic Unit
TM BadVaddr
Trap &
U
Status Memory Unit
(Coproc 0)
Cause
EPC
0
MIPS Processor Architecture
MIPS processor consists of an integer processing unit
(CPU) and a collection of coprocessors that perform
ancillary tasks or operate on other types of data such as
floating-point numbers.
Coprocessor 0 handles exceptions, interrupts, and the
virtual memory system
Coprocessor 1 is the floating-point unit.
MIPS is a load-store architecture, which means that only
load and store instructions access memory.
Computation instructions (like arithmetic & logical)
operate only on values in registers.
0
MIPS General-Purpose Registers
32 General Purpose Registers (GPRs)
Assembler uses the dollar notation to name
registers
$0 is register 0, $1 is register 1, …, and
$31 is register 31
All registers are 32-bit wide in MIPS32
Register $0 is always zero
Any value written to $0 is discarded
Assembler can refer to registers by name or by
number
It is easier for you to remember registers by
name
Assembler converts register name to its
corresponding number
Software defines names to all registers
To standardize their use in programs
Example: $8 - $15 are called $t0 - $t7
Used for temporary values
$0
= $zero
$16 = $s0
$1
= $at
$17 = $s1
$2
= $v0
$18 = $s2
$3
= $v1
$19 = $s3
$4
= $a0
$20 = $s4
$5
= $a1
$21 = $s5
$6
= $a2
$22 = $s6
$7
= $a3
$23 = $s7
$8
= $t0
$24 = $t8
$9
= $t1
$25 = $t9
$10 = $t2
$26 = $k0
$11 = $t3
$27 = $k1
$12 = $t4
$28 = $gp
$13 = $t5
$29 = $sp
$14 = $t6
$30 = $fp
$15 = $t7
$31 = $ra
0
MIPS Register Conventions
Name
Register
$zero
$0
$at
$1
Usage
Always 0
(forced by hardware)
Reserved for assembler use
$v0 – $v1
$2 – $3
Result values of a function
$a0 – $a3
$4 – $7
Arguments of a function
$t0 – $t7
$8 – $15
$s0 – $s7
$16 – $23
$t8 – $t9
$24 – $25
More temporaries
$k0 – $k1
$26 – $27
Reserved for OS kernel
Temporary Values
Saved registers
(preserved across call)
$gp
$28
Global pointer
(points to global data)
$sp
$29
Stack pointer
(points to top of stack)
$fp
$30
Frame pointer
(points to stack frame)
$ra
$31
Return address
(used by jal for function call)
MIPS CPU Registers
MIPS CPU contains 32 general-purpose registers that are
numbered $0. . . $31
Register $0 always contains the hardwired value 0 (constant zero
and can not be overwritten).
Registers also have symbolic names reflecting their conventional
use (Most of these conventions concern Procedure call and
return)
Register $at ($1) reserved for the assembler, Registers $k0 ($26)
and $k1($27) are reserved for the operating system. These
registers should not be used by user programs or compilers
Registers $a0 to $a3 ($4 to $7) are used to pass the first four
arguments to functions (remaining arguments are passed on the
stack).
Registers $v0 ($2) and $v1($3) are used to return values from
0
●
●
●
●
●
●
MIPS CPU Registers
Registers $t0 to $t9 ($8 to $15, $24, $25) are caller-saved
registers that are used to hold temporay quantities that need not
be preserved across calls
Register $s0 to $s7 ($16 to $23) are callee-saved registers that
hold long-lived values that should be preserved across calls.
Register $gp ($28) is a global pointer that points to the middle
of a 64K block of memory in the static data segment.
Register $sp ($29) is the stack pointer, which points to the last
location (stack top) on the stack.
Register $fp ($30) is the frame pointer
Registers $ra ($31) is the return address register used to hold
the return address from procedure call.
0
●
●
Stored-Program Concept
Computers built on 2 key principles:
1) Instructions are represented as numbers.
2) Therefore, entire programs can be stored in memory
to be read or written just like numbers (data).
Simplifies SW/HW of computer systems:
Memory technology for data also used for programs
Fetch & execute cycle
Instructions are fetched and put into a special register
Bits in the register "control" the subsequent actions
Fetch the “next” instruction and continue
0
●
●
●
●
●
●
Consequence I: Everything Addressed
Since all instructions and data are stored in memory as
numbers, everything has a memory address
Both branches and jumps use these
C pointers are just memory addresses: they can point
to anything in memory
Unconstrained use of addresses can lead to nasty bugs; up
to you in C; limits in Java
One register keeps address of instruction being
executed: Program Counter (PC)
Basically a pointer to memory: Intel calls it Instruction
Address Pointer, a better name
0
Consequence II: Binary Compatibility
●
●
●
●
●
●
●
●
Programs are distributed in binary form
Programs bound to specific instruction set
Different versions for Macintoshes and PCs
New machines want to run old programs/binaries as well as
programs compiled to new instructions
Leads to instruction set evolving over time
Selection of Intel 8086 in 1981 for 1st IBM PC is major
reason latest PCs still use 80x86 instruction set (Pentium
4); could still run program from 1981 PC today
A stored-program machine is reprogrammable
One important motivation was the need for a program to
increment or otherwise modify the address portion of
instructions
0
Simplicity favors regularity
Important
Fix the size
principles
of instructions (simplifies
in ISA
fetching &and
decoding)
hardware design
Fix the number of operands per instruction
All instructions have 3 operands
One destination, two operands
Operand order is fixed (destination first)
Smaller is faster
Limit the number of registers for faster access (typically 32 registers of 32 bits)
Make the common case fast
Most frequently executed instructions are the simplest operations of the ISA.
Include constants inside instructions (faster than loading them)
Design most instructions to be register-to-register
Good design demands good compromises
Keep formats as simple as possible (Different formats complicate decoding, but allow 32bit
instructions uniformly)
Fixed-size instructions compromise the size of constants
0
MIPS Assembly Language
●
●
●
●
●
Book Sections
2.1
2.2
2.3
2.4
0
Assembly Variables: Registers
●
In assembly language, each statement (called an Instruction),
executes exactly one of a short list of simple commands
●
Unlike in C (and most other High Level Languages), each line
of assembly code contains at most 1 instruction
Instructions are related to operations (=, +, -, *, /) in C or Java
Unlike HLL, assembly cannot use variables
Why not? Keep hardware simple
●
●
●
0
●
●
●
●
●
●
●
●
●
●
●
●
Assembly Variables: Registers
Assembly Operands are registers
limited number of special locations built directly into the hardware
operations can only be performed on these!
Benefit: Since registers are directly in hardware, they are very fast (faster
than 1 billionth of a second)
Different operand locations for different architectures
Stack, register, memory or a mix of them
Every architecture design after 1980 uses a load-store register architecture: ALU
operands are all registers; memory can only be accessed with load/store
Advantages of load-store register architectures
Registers are faster than memory
Registers are more efficient for a compiler to use
Drawback: Since registers are in hardware, there are a predetermined number of them
Solution: MIPS code must be very carefully put together to efficiently use
registers
0
●
●
●
Assembly
Variables:
Registers
MIPS has 32 registers
Why 32? Design principle: Smaller
Registers are numbered from 0 to 31
is faster
●
Each MIPS register is 32 bits wide
Groups of 32 bits called a word in MIPS
●
Registers are numbered from 0 to 31
●
Each register can be referred to by number or name
●
Number references:
$0, $1, $2, … $30, $31
●
●
By convention, each register also has a name to make it easier to code
$16 - $23
$s0 - $s7 for things that you want to keep around
(correspond to C variables)
$8 - $15
$t0 - $t7
(for temporary variables)
●
In general, use names to make your code more readable
●
●
(to make it easier code)
0
Comments in Assembly
●
Another way to make your code more readable: comments!
●
●
Hash (#) is used for MIPS comments
Anything from hash mark to end of line is a comment and
will be ignored
Every line of your comments must start with a #
Note: Different from C.
C comments have format
/* comment */
so they can span many lines
●
●
●
0
●
●
C, Java variables vs. registers
In C (and most High Level Languages) variables declared first
and given a type
Example:
int fahr, celsius;
char a, b, c, d, e;
●
Each variable can ONLY represent a value of the type it was
declared as (cannot mix and match int and char variables).
●
In Assembly Language, the registers have no type;
operation determines how register contents
are treated
0
MIPS Instruction Set
●
●
●
●
●
●
●
●
●
●
●
●
MIPS Instructions can be classified into following categories
Integer Arithmetic
Arithmetic, logical, and shift instructions
Data Transfer
Load and store instructions that access memory
Data movement and conversions
Jump and Branch
Flow-control instructions that alter the sequential sequence
Floating Point Arithmetic
Instructions that operate on floating-point registers
Miscellaneous
Instructions that transfer control to/from exception handlers
Memory management instructions
0
0
0
MIPS Instruction Formats
●
●
●
●
●
●
●
●
Minimum number of instructions required
Information flow: load/store
Logic operations: logic and/or/nor, shift
Arithmetic operations: addition, subtraction, etc.
Branch operations: bne, beq
Jump operations: j, jal
Instructions have different number of operands
32 bits representing a single instruction
Name
Fields
Comments
Field size
6 bits
5 bits
5 bits
5 bits
5 bits
6 bits
All MIPS instructions 32 bits
R-format
op
rs
rt
rd
shamt
funct
Arithmetic instruction format
I-format
op
rs
rt
address/immediate
J-format
op
target address
Transfer, branch, imm. format
Jump instruction format
0
MIPS Addition and Subtraction(1/5)
Syntax of Instructions: op dest, src1, src2
Example: add $t0, $s1, $s2 (in MIPS)
where:
# add rd, rs, rt
Op: operation by name
Dest: operand getting result (“destination”)
Src1: 1st operand for operation (“source1”)
Src2: 2nd operand for operation (“source2”)
●
●
●
Operands must be registers in MIPS
Register set of a machine is a limited number of special locations built directly
into the hardware
Syntax is rigid:
All instructions have 3 operands
One destination, two operands
Operand order is fixed (destination first)
Why? Keep Hardware simple via regularity
Regularity makes implementation simples
Simplicity enables higher performance at lower cost
Each line of assembly code contains at most 1 instruction
0
Addition and Subtraction of Integers (2/5
Addition in Assembly
Example:add $t0,$s1,$s2 (in MIPS)
# add rd, rs, rt
Equivalent to: a = b + c (in C)
where MIPS registers $t0,$s1,$s2 are
associated with C variables a, b, c
0
Subtraction in Assembly
Example: sub $s3,$s4,$s5 (in MIPS) # sub rd, rs, rt
Equivalent to:
d=e-f
(in C)
where MIPS registers $s3,$s4,$s5 are associated with
C variables d, e, f
0
Overflow in Arithmetic (1/2)
Reminder: Overflow occurs when there is a mistake in arithmetic
due to the limited precision in computers.
Example (4-bit unsigned numbers):
+15
+3
+18
1111
0011
10010
But we don’t have room for 5-bit solution, so the solution
would be 0010, which is +2, and wrong.
0
Overflow in Arithmetic (2/2)
●
●
●
●
●
●
●
●
●
●
●
Some languages detect overflow (Ada), some don’t (C)
MIPS solution is 2 kinds of arithmetic instructions to recognize 2 choices:
add (add), add immediate (addi) and subtract (sub) cause overflow to
be detected
addi: overflow causes an arithmetic exception
In case of overflow, result is not written to destination register
add unsigned (addu), add immediate unsigned (addiu) and subtract
unsigned (subu) do not cause overflow detection
addiu: same operation as addi but overflow is ignored
Immediate constant for addi and addiu is signed
No need for subi or subiu instructions
Compiler selects appropriate arithmetic
MIPS C compilers produce addu, addiu, subu
0
●
●
●
MIPS - Arithmetic Instructions
add (add registers signed)
Instruction Mnemonic :
add rd, rs, rt ;where rs, rt, rd are registers, overflow detected
Meaning :
rd rs + rt ; signed add operation
Example :
add $s1, $s2, $s3
; $s1 $s2 + $s3
addu (add registers unsigned)
Instruction Mnemonic :
addu rd, rs, rt ;where rs, rt, rd are registers, overflow not detected
Meaning :
rd rs + rt ; unsigned add operation
Example :
addu $s1, $s2, $s3
; $s1 $s2 + $s3
0
●
●
●
●
●
●
MIPS - Arithmetic Instructions
sub (subtract registers signed)
Instruction Mnemonic :
sub rd, rs, rt ;where rs, rt, rd are registers, overflow detected
Meaning :
rd rs - rt ; signed subtraction
Example :
sub $s1, $s2, $s3
; $s1 $s2 - $s3
subu (subtract registers unsigned)
Instruction Mnemonic :
subu rd, rs, rt ;where rs, rt, rd are registers, overflow not detected
Meaning :
rd rs - rt
; unsigned subtraction
Example :
subu $s1, $s2, $s3
; $s1 $s2 - $s3
0
MIPS Arithmetic with Registers
Example:
C code:
a=b+c
MIPS code:
C code:
add a,b,c
a = b + c + d;
MIPS code:
add a, b, c
add a, a, d
Design principle: Hardware implementation is simplified via regularity
0
Addition and Subtraction of Integers (3/5)
How do the following C statement?
●
a = b + c + d - e;
mapping
a $s0
b
$s1
c
$s2
d
$s3
e
$s4
0
Addition and Subtraction of Integers (4/5)
Break into multiple instructions
add $t0, $s1, $s2
# temp = b + c
add $t0, $t0, $s3
# temp = temp + d
sub $s0, $t0, $s4
# a = temp - e
Notice: A single line of C may break up into several lines of
MIPS.
Notice: Everything after the hash mark on each line is ignored
(comments)
0
Addition/Subtraction Example (5/5)
Consider the translation of: f = (g+h) – (i+j)
Compiler allocates registers to variables
Assume that f, g, h, i, and j are allocated registers $s0($16), $s1($17),
$s2($18), $s3($19), $s4($20)
i.e., $s0
f, $s1
g, $s2
h, $s3
i, $s4
j
• Translation of: f = (g+h) – (i+j)
addu $t0, $s1, $s2
# $t0 = g + h
addu $t1, $s3, $s4
# $t1 = i + j
subu $s0, $t0, $t1
# f = (g+h)–(i+j)
– Temporary results are stored in $t0($8) and $t1($9)
– Final result, i.e., computed f value is stored in $s0
0
Register Zero
●
One particular immediate, the number zero (0), appears very
often in code
●
So we define register zero ($0 or $zero) to always have the
value 0
Often used to move values or set constant values
f = g (in C copy contenet)
add $s0,$s1,$zero (in MIPS)
MIPS registers $s0, $s1 are associated with C variables
f, g
●
●
●
●
●
●
$zero defined in hardware
Instruction add $zero,$zero,$s0 will not do anything!
0
Register Immediate Instruction
●
Immediates are numerical constants.
●
They appear often in code, so there are special instructions for
them.
Add Immediate:
●
●
op
dest, srcA, immediate
addi $s0,$s1,10 (in MIPS)
f = g + 10 (in C)
where MIPS registers $s0,$s1 are associated with C variables f, g
Syntax similar to add instruction, except that last argument is a
number instead of a register.
0
Immediates
There is no Subtract Immediate in MIPS: Why?
Limit types of operations that can be done to absolute minimum
if an operation can be decomposed into a simpler operation, don’t include
it
(addi …, -X)= (subi …, X) => so no subi
addi $s0,$s1,-10 (in MIPS)
f = g - 10 (in C)
where MIPS registers $s0,$s1 are associated with C variables f, g
0
addi (add immediate signed )
Instruction Mnemonic :
addi rd, rs, const ;where rs, rd are registers, const is a 16-bit constant value
;overflow detected
Meaning :
rd rs + const
Example :
addi $s1, $s2, 100 ; $s1 $s2 + 100
addiu (add immediate unsigned)
Instruction Mnemonic :
addiu rd, rs, const ;where rs, rd are registers, const is a 16-bit constant value
;overflow not detected
Meaning :
rd rs + const
Example :
addiu $s1, $s2, 100
; $s1 $s2 + 100
0
●
Different formats complicate decoding, but allow 32bit instructions uniformly
Keep formats as simple as possible
●
Good design demands good compromises
●
0
Assembly Operands: Memory
0
Assembly Operands: Memory
●
C variables map onto registers; what about large data structures
like arrays?
●
Memory contains such data structures
But MIPS arithmetic instructions only operate on registers,
never directly on memory.
Data transfer instructions transfer data between registers and
memory:
Memory to register
Register to memory
●
●
●
●
0
Memory Organization
Think of memory as a large, single-dimension array
A memory address is an index into the array
"Byte addressing" means that the index points to a byte of
memory
We can address it simply by supplying a pointer to a memory
address
Other times we want to be able to offset from this pointer.
0
8 bits of data
1
8 bits of data
2
8 bits of data
3
8 bits of data
4
8 bits of data
5
8 bits of data
6
8 bits of data
...
0
Memory Organization
Bytes are nice, but most data items use larger "words"
For MIPS, a word is 32 bits or 4 bytes
0
32 bits of data
4
8
32 bits of data
32 bits of data
12 32 bits of data
MIPS register holds 32 bits of data
232 bytes with byte addresses from 0 to 232-1 ...
230 words with byte addresses 0, 4, 8, ... 232-4
Words are aligned: they must start at addresses that are multiples of 4
0
Addressing: Byte vs. word
●
Every word in memory has an address, similar to an index
in an array
●
Early computers numbered words like C numbers elements
of an array:
Memory[0], Memory[1], Memory[2], …
●
Called the “address” of a word
•
Computers needed to access 8-bit bytes as well as words (4 bytes/word)
•
Today machines address memory as bytes, (i.e.,“Byte Addressed”) hence 32-bit (4
byte) word addresses differ by 4
Memory[0], Memory[4], Memory[8], …
•
0
More Notes about Memory: Alignment
●
MIPS requires that all words start at byte addresses that are
multiples of 4 bytes
0
Aligned
Not
Aligned
•
1
2
3
Last hex digit
of address is:
0, 4, 8, or Chex
1, 5, 9, or Dhex
2, 6, A, or Ehex
3, 7, B, or Fhex
Called Alignment: objects must fall on address that is multiple of their size.
0
●
●
●
●
●
Notes about Memory
Pitfall: forgetting that sequential word addresses in machines do
not differ by 1
To transfer a word, the sum of the base address and the offset
must be a multiple of 4 (to be word aligned)
0
Aligned
Not
Aligned
1
2
3
Last hex digit of address
0, 4, 8, or Chex
1, 5, 9, or Dhex
2, 6, A, or Ehex
What if more variables than registers?
3, 7, B,
or Fhex
Compiler tries to keep most frequently
used
variable in
registers
Less common in memory: spilling
0
• Instructions that transfer data between memory & registers
• Programs include variables such as arrays and objects
• Such variables are stored in memory
• Load Instruction:
– Transfers data from memory to a register
• Store Instruction:
– Transfers data from a register to memory
• Memory address must be specified by load and store
0
Data Transfer: Memory to Reg (1/4)
●
●
●
●
●
To transfer a word of data, we need to specify two things:
Register: specify this by # ($0 - $31) or symbolic name ($s0,
…, $t0, …)
Memory address: more difficult
Think of memory as a single one-dimensional array, so we
can address it simply by supplying a pointer to a memory
address.
Other times, we want to be able to offset from this pointer.
0
Data Transfer: Memory to Reg (2/4)
●
●
●
●
●
●
To specify a memory address to copy from, specify two
things:
A register containing a pointer to memory
A numerical offset (in bytes)
The desired memory address is the sum of these two values.
Example: 8($t0)
specifies the memory address pointed to by the value
in $t0, plus 8 bytes
0
●
●
●
●
●
●
Data Transfer: Memory to Reg (3/4)
MIPS has two basic data transfer instructions for accessing memory
lw $t0, 4($s3)
#load word from memory
sw $t0, 8($s3)
#store word to memory
Load instruction syntax:
lw reg1, offset(reg2)
Operator name: lw (meaning Load Word, so 32 bits or one word are loaded at a
time)
Reg1: register that will receive the transferred data (destination)
Offset: a numerical offset in bytes
Reg2: register containing pointer to memory, called base register
0
●
●
●
●
Data Transfer: Memory to Register (4/4)
Data flow
Example: lw $t0,32($s3)
This instruction will take the pointer in $s3, add 32 bytes to
it, and then load the value from the memory pointed to by
this calculated sum into register $t0
Notes:
$s3 is called the base register
32 is called the offset
offset is generally used in accessing elements of array or
structure: base register points to beginning of array or
structure
0
●
●
●
●
●
Data Transfer: Register to Memory
Also want to store from register into memory
Store instruction syntax is identical to Load’s
MIPS Instruction Name:
sw (meaning Store Word, so 32 bits or one word are
loaded at a time)
Data flow
Example:
sw $t0,48($s3)
This instruction will take the pointer in $s3, add 48 bytes to it,
and then store the value from register $t0 into that memory
address
Remember: “Store INTO memory”
0
Example
C code:
A[12] = h + A[8];
MIPS code:
lw $t0, 32($s3) # base address of array A is in $s3
# base register
# 1 array element is 4-byte
#alignment is multiple of 4
# index 8 requires offset of 32
# temp t0 = A[8]
add $t0, $s2, $t0 # h is associated with $s2
sw $t0, 48($s3) # offset=12*4=48
Can refer to registers by name (e.g., $s2, $t2) instead of number
Store word has destination last
Remember arithmetic operands are registers, not memory!
Can’t write: add 48($s3), $s2, 32($s3)
0
Compilation with Memory
●
●
●
●
●
●
●
What offset in lw to select A[5] in C?
4x5=20 to select A[5]: byte v. word
Compile by hand using registers:
g = h + A[5];
g: $s1, h: $s2, $s3:base address of A
1st transfer from memory to register:
lw
$t0,20($s3)
# $t0 gets
A[5]
Add 20 to $s3 to select A[5], put into $t0
Next add it to h and place in g
add $s1,$s2,$t0
# $s1 = h+A[5]
0
Notes about Memory
●
Many an assembly language programmer has toiled over
errors made by assuming that the address of the next word
can be found by incrementing the address in a register by 1
instead of by the word size in bytes.
●
So remember that for both lw and sw, the sum of the base
address and the offset must be a multiple of 4 (to be word
aligned)
0
Role of Registers vs. Memory
●
●
●
●
●
●
●
●
What if more variables than registers?
Compiler tries to keep most frequently used variable in
registers
Less common in memory: spilling
Why not keep all variables in memory?
Smaller is faster:
registers are faster than memory
Registers more versatile:
MIPS arithmetic instructions can read 2, operate on
them, and write 1 per instruction
MIPS data transfer only read or write 1 operand per
instruction, and no operation
0
Pointers vs. Values
●
●
●
●
●
Key concept: a register can hold any 32-bit value
That value can be a signed int, an unsigned int, a pointer
(memory address), and so on
If you write add $t2,$t1,$t0, then $t0 and $t1 better
contain values
If you write lw $t2,0($t0), then $t0 better contains a
pointer
Don’t mix these up!
0
opcod
e
100011
r
s
01001
r
t
10000
r
d
00000 10010 01000 0100
0
0
101011
01001
01000
sham func
t
t
1200
0000 10000
0
0
1200
• Translate A[300] = A[300] + h (A is an array of words)
– Assume that address of array A is stored in register $t1, h in $s2
lw $t0, 1200($t1)
Add $t0, $s2, $t0
sw $t0, 1200($t1)
0
• Load Word Instruction (Word = 4 bytes in MIPS)
lw Rt, imm16 (Rs) # Rt = MEMORY[Rs+ , imm16 ]
• Store Word Instruction
sw Rt, , imm16 (Rs) # MEMORY[Rs+ , imm16 ] = Rt
• Base or Displacement addressing is used
– Memory Address = Rs (base) + immediate16 (displacement)
– Immediate16 is sign-extended to have a signed displacement
• Base or Displacement Addressing is used
– Memory Address = Rs (base) + , immediate16 (displacement)
• Two variations on base addressing
– If Rs = $zero = 0 then Address = , immediate16 (absolute)
– If , immediate16 = 0 then Address = Rs (register indirect)
0
Data Transfer Instructions
lw (Load word)
Instruction Mnemonic :
lw rd, const(rs)
;where rs, rd are registers, const is a 16-bit
displacement
lw rd, addr
; where addr is the label of the memory location
to be accessed
Meaning :
rd Memory[rs + const] ; load word from memory to register
Example :
lw $s1, 100($s2)
; $s1 Memory[$s2+100]
lw $s1, NUM1
; load register $s1 with a word from memory
location NUM1
0
lh (Load halfword with sign extension)
●
●
●
Instruction Mnemonic :
lh rd, const(rs)
;where rs, rd are registers, const is a 16-bit
displacement
lh rd, addr
; where addr is the label of the memory location to be
accessed
Meaning :
rd Memory[rs + const] ; load halfword from memory to register
Example :
lh $s1, 100($s2)
; $s1 Memory[$s2+100]
lh $s1, NUM1
; load register $s1 with a half-word from memory
location NUM1
0
●
●
●
lhu (Load halfword unsigned – without sign
extension)
Instruction Mnemonic :
lhu rd, const(rs)
;where rs, rd are registers, const is a 16-bit
displacement
lhu rd, addr
; where addr is the label of the memory location to be
accessed
Meaning :
rd Memory[rs + const] ; load halfword from memory to register
Example :
lhu $s1, 100($s2) ; $s1 Memory[$s2+100]
lhu $s1, NUM1
; load register $s1 with a half-word from memory
location NUM1
0
lb (Load byte with sign extension)
●
●
●
Instruction Mnemonic :
lb rd, const(rs)
;where rs, rd are registers, const is a 16-bit displacement
lb rd, addr
; where addr is the label of the memory location to be accessed
Meaning :
rd Memory[rs + const] ; load byte from memory to register
Example :
lb $s1, 100($s2)
; $s1 Memory[$s2+100]
lb $s1, NUM1
; load register $s1 with a byte from memory location
NUM1
0
lbu (Load byte unsigned –
without sign extension)
●
●
Instruction Mnemonic :
lbu rd, const(rs)
;where rs, rd are registers, const is a 16-bit
displacement
lbu rd, addr
; where addr is the label of the memory location to
be accessed
Meaning :
rd Memory[rs + const] ; load unsigned byte from memory to register
Example :
lbu $s1, 100($s2) ; $s1 Memory[$s2+100]
lbu $s1, NUM1
; load register $s1 with a byte from memory
location NUM1
0
0
Loading & Storing Bytes
In addition to word data transfers, MIPS has byte data transfers for
characters (char type)
Load byte: lb; store byte: sb
Same format as lw, sw
What to do with other 24 bits in the 32 bit register?
lb: sign extends to fill upper 24 bits
xxxx xxxx xxxx xxxx xxxx xxxx
…is copied to “sign-extend”
xzzz zzzz
byte
This bitloaded
Normally do not want to sign extend chars
MIPS instruction that does not sign extend when loading bytes
-- load byte unsigned: lbu
0
Load and Store Byte and Halfword
• The MIPS processor supports the following data formats:
– Byte = 8 bits, Halfword = 16 bits, Word = 32 bits
• Load & store instructions for bytes and halfwords
– lb = load byte, lbu = load byte unsigned, sb = store byte
– lh = load half, lhu = load half unsigned, sh = store halfword
• Load expands a memory data to fit into a 32-bit register
• Store reduces a 32-bit register to fit in memory
0
Instruction Representation
●
●
Book Sections
2.5
0
Instructions as Numbers (1/2)
●
How do we represent instructions?
Remember: Computer only understands 1s and 0s
MIPS wants simplicity: since data is in words, make
instructions be words too
One word is 32 bits, so divide instruction word into “fields”.
●
Each field tells computer something about instruction.
●
●
●
0
●
●
●
●
Instructions as Numbers (2/2)
We could define different fields for each
instruction, but MIPS is based on simplicity, so
define 3 basic types of instruction formats:
R-format
I-format
J-format
0
Instruction Formats
I-format: immediate format Instructions with immediates lw and
sw (since the offset counts as an immediate), and the branches
(beq and bne),
(but not the shift instructions; later)
Data transfer instructions (since the offset counts as an
immediate)
Branches (beq and bne)
J-format: jump format
j and jal (more details later)
R-format: used for all other instructions
It will soon become clear why the instructions have been
partitioned in this way
0
R-Format Instructions (1/5)
●
Define “fields” of the following number of bits each:
6 + 5 + 5 + 5 + 5 + 6 = 32
6
5
5
5
5
6
• For simplicity, each field has a name:
opcode
rs
rt
rd
sham
t
func
t
• Important: each field is viewed as a 5- or 6bit unsigned integer, not as part of a 32-bit
integer.
•
Consequence: 5-bit fields can represent any
number 0-31, while 6-bit fields can represent
any number 0-63.
0
R-Format Instructions (2/5)
What do these field integer values tell us?
●
●
●
●
●
opcode: partially specifies what instruction it is
Specifies the operation of the instruction
Also specifies the format of the instruction
Note: This number is equal to 0 for all R-Format
instructions.
funct: combined with opcode, this number exactly specifies
the instruction
Up to 26= 64 functions can be defined for the same opcode
Question: Why aren’t opcode and funct a single
12-bit field?
●
●
Answer: We’ll answer this later.
0
●
●
●
●
R-Format Instructions (3/5)
Three Register Operands (common to many
instructions):
rs (Source Register): generally used to specify
register containing first operand
rt (Target Register): generally used to specify
register containing second operand (note that
name is misleading)
rd (Destination Register): generally used to
specify register which will receive result of
computation
0
R-Format Instructions (4/5)
Notes about register fields:
●
Each register field is exactly 5 bits, which means
that it can specify any unsigned integer in the range
0-31. Each of these fields specifies one of the 32
registers by number.
The word “generally” was used because there are
exceptions that we’ll see later. E.g.,
●
●
●
●
mult and div have nothing important in the rd field
since the dest registers are hi and lo
mfhi and mflo have nothing important in the rs and
rt fields since the source is determined by the instruction
0
R-Format Instructions (5/5)
Final field:
shamt: This field contains the amount a shift
instruction will shift by. Shifting a 32-bit word by
more than 31 is useless, so this field is only 5 bits
(so it can represent the numbers 0-31).
This field is set to 0 in all but the shift instructions.
0
●
●
●
R-Format Example
(1/2)
MIPS Instruction:
Add rd, rs, rt
add $t0,$s1,$s2
opcode = 0
funct = 32
rd = 8 (destination)
rs = 17 (first operand)
rt = 18 (second operand)
shamt = 0 (not a shift)
0
R-Format Example (2/2)
MIPS Instruction: add
$t0,$s1,$s2 #Add
rd, rs, rt
Encode to decide the value of each field
opcode = 0, funct = 32 (look up in table in book)
rd = 8 (destination)
rs = 17(first operand), rt = 18 (second operand)
shamt = 0 (not a shift)
opcode
rd
shamt funct
Decimal rs
number perrt
field representation
0Binary number
17 per field
18 representation
8
0
32
000000
1000
0100
Machine
language1001
instruction
in hexa: 0000 100000
Hex representation:
0232
1
0 4020hex0
0
he
x
0
●
Translate: addu $t0,$s1,$s2 to binary code
0
I-Type Format
• Constants are used quite frequently in programs
The R-type shift instructions have a 5-bit shift amount constant
What about other instructions that need a constant?
• I-Type: Instructions with Immediate Operands
• 16-bit immediate constant is specified immediately in the instruction
Rs is the source register number
Rt is now the destination register number (for R-type it was Rd)
Examples of I-Type ALU Instructions:
Add immediate: addi $s1, $s2, 10 # $s1 = $s2 + 10
OR immediate: ori $s1, $s2, 10
# $s1 = $s2 | 10
(1) may cause overflow
(2) sign extension immediate
0
0
I-Format Instructions (1/4)
What about instructions with immediates?
5-bit field only represents numbers up to the value 31: immediates
may be much larger
Ideally, MIPS would have only one instruction format for simplicity:
unfortunately, we need to compromise
●
●
●
●
●
●
●
●
Still, try to define new instruction format that is partially consistent
with R-format
The first three fields of both formats are the same size and have
the same names
The rest three fields in R-format are merged to form a single field
for the immediate operand
Define new instruction format that is partially consistent with R-format:
First notice that, if instruction has immediate, then it uses at most 2
registers.
0
I-Format Instructions (2/4)
●
Define “fields” of the following number of
bits each: 6 + 5 + 5 + 16 = 32 bits
6
5
5
16
• Again, each field has a name:
opcode
rs
rt
immediat
e
• Key Concept: Only one field is inconsistent
with R-format. Most importantly, opcode
is still in same location.
0
I-Format Instructions (3/4)
6
opcode
●
●
●
●
●
5
rs
5
rt
16
immediat
e
What do these fields mean?
opcode: same as before except that, since there’s no
funct field, opcode uniquely specifies an instruction
in I-format
This also answers question of why R-format has two 6bit fields to identify instruction instead of a single 12-bit
field: in order to be consistent with other formats.
rs: specifies the only register operand (if there is one)
rt: specifies register which will receive result of
computation (this is why it’s called the target register
“rt”)
0
I-Format Instructions (4/4)
The immediate field
Used to specify immediates for instructions with a numerical
constant operands
Used to specify address offset in data transfer instructions: lw,
sw, etc.
Used to specify branch address in bne and beq
Range
Both positive and negative numbers
16 bits can be used to represent immediate up to 216 different values
What if the number we want to represent is out of the range?
0
●
●
●
●
●
●
●
●
●
Large Immediates
Range of immediates is limited
Length of immediate field is 16 bits
Considered as a signed number (sign bit)
Arithmetic operands or address offset can be larger
32-bit data / address in MIPS
We need a way to deal with a 32-bit immediate in any Iformat instruction
Solution:
Handle it in software + new instruction
Don’t change the current instructions: instead, add a new
instruction to help out
0
long constant
●
addi $s0, $0,75000 #needs more than 16 bits
●
Load 32 bits into a register using load upper 16 bits than load
lower 16 bits
●
0000 0000 0000 0001 0010 0100 1111 1000
lui $s0,1
0000 0000 0000 0001 0000 0000 0000 0000
ori $s0,$s0,9464
0000 0000 0000 0001 0010 0100 1111 1000
●
●
●
●
0
I-Format Problems (1/3)
●
●
●
●
Problem 1:
Chances are that addi, lw, sw and slti
will use immediates small enough to fit in the
immediate field.
…but what if it’s too big?
We need a way to deal with a 32-bit
immediate in any I-format instruction.
I-Format Problems (2/3)
●
●
●
●
●
●
●
Solution to Problem 1:
Handle it in software + new instruction
Don’t change the current instructions: instead, add a new
instruction to help out
New instruction:
lui
register, immediate
stands for Load Upper Immediate
takes 16-bit immediate and puts these bits in the upper half (high
order half) of the specified register
sets lower half to 0s
I-Format Problems (3/3)
●
●
●
Solution to Problem 2
So how does lui help us?
Example:
addi
$t0,$t0, 0xABABCDCD
becomes:
lui
$at, 0xABAB
ori
$at, $at, 0xCDCD
add
$t0,$t0,$at
●
●
Now each I-format instruction has only a 16-bit
immediate.
Wouldn’t it be nice if the assembler would this for
us automatically? (later)
Large Immediates
H
W
New instruction:
●
lui register, immediate
Load Upper Immediate
Takes 16-bit immediate and puts these bits in the
upper half (high order half) of the specified
register; lower half is set to 0s
Example:
●
●
●
●
●
Want to write: addi $t0,$t0, 0xABABCDCD
Need to write a sequence instead:
lui
$at, 0xABAB
ori
$at, $at, 0xCDCD
add
$t0,$t0,$at
0
I-Format Problems (0/3)
Problem 2: Unsigned
●
# sign-extended?
addiu, sltiu, sign-extends immediates to 32
bits. Thus, # is a “signed” integer.
●
Rationale
●
addiu so that can add without overflow
sltiu suffers so that we can have simple HW
●
●
●
●
Does this mean we’ll get wrong answers?
No, it means assembler has to handle any unsigned
immediate 215 ≤ n < 216 (I.e., with a 1 in the 15th bit
and 0s in the upper 2 bytes) as it does for numbers that
are too large.
I-Format Example
MIPS Instruction: addi $21,$22,-50
●
Encode for each field
●
●
●
●
●
●
●
●
opcode = 8 (look up in table in book)
Negative number
rs = 22 (register containing operand)
encoding: 2’s
complement
rt = 21 (target register)
immediate = -50 (by default, this is decimal)
Decimal number per field representation
number per
8 Binary 22
21 field representation
-5
0
Hexadecimal representation: 22D5 FFCEhex
001000
1010 584,449,998ten
1111111111001110
Decimal1011
representation:
0
1
0
●
●
●
●
lui (Load upper immediate)
Instruction Mnemonic :
lui rd, const ;where rd is a register, const is a 16-bit number
Meaning :
rd const*216 ; load constant in upper 16 bits of register
Example :
lui $s1, 100
; $s1 100 * 216
0
32-bit Constants
●
I-Type instructions can have only 16-bit constants
●
What if we want to load a 32-bit constant into a register?
Can’t have a 32-bit constant in I-Type instructions
We have already fixed the sizes of all instructions to 32 bits
●
●
●
●
●
Solution: use two instructions instead of one
Suppose we want: $s1=0xAC5165D9 (32-bit constant)
lui: load upper immediate
0
Examples: I-Type ALU Instructions
• Examples: assume A, B, C are allocated $s0, $s1, $s2
• No need for subi, because addi has signed immediate
• Register 0 ($zero) has always the value 0
0
Peer Instruction
Which instruction has same representation as 35ten?
1. add $0, $0, $0
opcod
r
r
r
sham func
2. subu $s0,$s0,$s0
e
s
t
d
t
t
3. lw $0, 0($0)
opcod
r
r
r
sham func
4. addi $0, $0, 35
e
s
t
d offse
t
t
opcod
r
r
5. subu $0, $0, $0
e
s
t
t
6. Trick question!
opcod
r
r
immediat
e
s
opcod
r
Instructions are not
numbers
Registers numbers and names:
e
s
t
r
t
r
d
e
sham
t
func
t
0: $0, .. 8: $t0, 9:$t1, ..15: $t7, 16: $s0, 17: $s1, .. 23: $s7
Opcodes and function fields (if necessary)
add: opcode = 0, funct = 32
subu: opcode = 0, funct = 35
addi: opcode = 8
lw: opcode = 35
0
Peer Instruction Answer
Which instruction bit pattern = number 35?
1. add $0, $0, $0
0
0
0
0
0
32
2. subu $s0,$s0,$s0
0
16
16
16
0
35
35
0
0
0
8
0
0
35
0
0
0
3. lw $0, 0($0)
4. addi $0, $0, 35
5. subu $0, $0, $0
0
0
35
6. Trick question!
Instructions != numbers
Registers numbers and names:
0: $0, …, 8: $t0, 9:$t1, …,16: $s0, 17: $s1, …,
Opcodes and function fields
add: opcode = 0, function field = 32
subu: opcode = 0, function field = 35
addi: opcode = 8
lw: opcode = 35
2/23/20
96
Immediates in Conditional Branches
Branch instructions bne and beq
●
opcode
●
●
●
rt
immediate
Field rs and rt specify registers to compare
Field immediate specify branch address
●
●
rs
●
16 bit is too small since we have 32-bit pointer to memory
Observation
Branches are used for if-else, while-loop, for-loop: tend to
branch to a nearby instruction
We only need to know the difference between the branch
target and the current instruction address, which is much
smaller and 16-bit addressing might suffice in most cases
0
J-Type Format
J-type format is used for unconditional jump instruction:
●
j label
# jump to label
...
●
●
label:
26-bit immediate value is specified in the instruction
Immediate constant specifies address of target instruction
0
Unconditional Jump Instructions
j (jump to target address)
Instruction Mnemonic :
j addr
;where addr is the label of the target address
Meaning :
jump to the target address location specified by the label addr in the instruction
Example :
j loop
; goto location having the label loop
0
●
●
●
●
●
●
●
●
●
●
●
J-Format Instructions (1/5)
For general jumps (j and jal), we may jump to anywhere in memory.
Ideally, we could specify a 32-bit memory address to jump to.
Unfortunately, we can’t fit both a 6-bit opcode and a 32-bit address into a
single 32-bit word, so we compromise.
For branches, we assumed that we won’t want to branch too far, so we can
specify change in PC.
Branch Address Boundary
Branch instructions use I-Type format (16-bit immediate constant)
PC-relative addressing:
Count number of instructions to branch from next instruction
Positive constant => Forward Branch,
Negative constant => Backward branch
At most ± 215 instructions to branch (most branches are near)
J-Format Instructions (2/5)
J-format is used by MIPS jump instructions
6-bit opcode + 26-bit jump address
●
●
6 bits
26 bits
•
opcode
•
•
•
j and jal
As usual, each field has a name:
target
address
• Key Concepts
Keep opcode field identical to R-format and I-format for consistency.
Combine all other fields to make room for large target address.
Goto statements and function calls tend to have larger offsets than branches and
loops
J-Format Instructions (3/5)
For now, we can specify 26 bits of the 32-bit bit address.
Optimization:
Note that, just like with branches, jumps will only jump to
word aligned addresses, so last two bits are always 00 (in
binary).
So let’s just take this for granted and not even specify
them.
J-Format Instructions (4/5)
●
●
●
●
●
●
Now specify 28 bits of a 32-bit address .
Where do we get the other 4 bits?
By definition, take the 4 highest order bits from the PC.
Technically, this means that we cannot jump to anywhere
in memory, but it’s adequate 99.9999…% of the time, since
programs aren’t that long
only if straddle a 256 MB boundary (228)
If we absolutely need to specify a 32-bit address, we can
always put it in a register and use the jr instruction.
J-Format Instructions (5/5)
●
●
New PC = { PC[31 30 29 28], target address, 00 }
Note: { , , } means concatenation
●
●
{ 4 bits , 26 bits , 2 bits } = 32 bit address
{ 1010 || 11111111111111111111111111 || 00 } =
10101111111111111111111111111100
MIPS Logical & Shift Operations
Book Section: 2.6
0
Bitwise Operations
Up until now, we’ve done arithmetic (add, sub,addi ),
memory access (lw and sw), and branches and jumps.
All of these instructions view contents of register as a
single quantity (such as a signed or unsigned integer)
New Perspective: View register as 32 raw bits rather
than as a single 32-bit number
Since registers are composed of 32 bits, we may want to
access individual bits (or groups of bits) rather than the
whole.
Introduce two new classes of instructions:
Logical and Shift Operations
0
●
●
●
●
●
Bitwise manipulation
Useful for extracting and inserting groups of bits in a word
MIPS Logical Operators are all bitwise, meaning that bit 0 of the
output is produced by the respective bit 0’s of the inputs, bit 1 by
the bit 1’s, etc.
C: Bitwise AND is & (e.g., z = x & y;)
C: Bitwise OR is | (e.g., z = x | y;)
0
Logical Operators
●
Logical bitwise operations: and, or, xor, nor Truth Table:
standard table listing all possible combinations of inputs and
resultant output for each. E.g.,
and instruction is used to clear bits: x and 0 = 0
or instruction is used to set bits: x or 1 = 1
xor instruction is used to toggle bits: x xor 1 = not x
nor instruction can be used as a not, how?
nor $s1,$s2,$s2 is equivalent to not $s1,$s2
0
Logical Operators
Logical instruction syntax:
op dest, src1, src2
and $s0,$s1,$s2
●
Op: operation name (and, or, nor)
Dest: register that will receive value
Src1: first operand (register)
Src2: second operand (register) or immediate
●
●
●
●
Accept exactly 2 inputs and produce 1 output
●
Benefit: rigid syntax simpler hardware
Why nor?
●
●
●
●
nor $t0, $t1, $t2
# $t0 = not ($t1 or $t2)
and, or: Both of these expect the third argument to be a
register
0
Examples:
●
●
●
●
HW
Assume $s1 = 0xabcd1234 , $s2 = 0xffff0000
and $s0,$s1,$s2
# $s0 = 0xabcd0000
or $s0,$s1,$s2
# $s0 = 0xffff1234
xor $s0,$s1,$s2
# $s0 = 0x54321234
nor $s0,$s1,$s2
# $s0 = 0x0000edcb
S1
1010 1011 1100 1101 0001 0010 0011 0100
S2
1111 1111 1111 1111 0000 0000 0000 0000
and 1010 1011 1100 1101 0000 0000 0000 0000
OR 1111 1111 1111 1111 0001 0010 0011 0100
XOR 0101 0100 0011 0010 0001 0010 0011 0100
NOR 0000 0000 0000 0000 1110 1101 1100 1011
0
and (logical and)
Instruction Mnemonic :
and rd, rs, rt
where rs, rt, rd are registers,
Meaning :
rd rs & rt
Example :
and $s1, $s2, $s3 ;
$s1 $s2 & $s3
0
or (logical or)
Instruction Mnemonic :
or rd, rs, rt
;where rs, rt, rd are registers,
Meaning :
rd rs | rt
Example :
or $s1, $s2, $s3 ;
$s1 $s2 | $s3
0
xor (logical Exclusive-or)
Instruction Mnemonic :
xor rd, rs, rt
;where rs, rt, rd are registers,
Meaning :
rd
rs rt
Example :
xor $s1, $s2, $s3
; $s1
$s2 $s3
0
nor (logical nor)
Instruction Mnemonic :
nor rd, rs, rt
Meaning :
rd rs nor rt
Example :
nor $t0, $t1, $t3
;where rs, rt, rd are registers,
; $t0
$t1 nor $t3
0
Logical Operators
Immediate operands
andi rd, rs, const
H
W
andi, ori: both expect the third argument to be an
immediate
(3) zero extension
0
andi (logical and immediate)
Instruction Mnemonic :
andi rd, rs, const ;where rs, rd are registers, const is a 16-bit constant
Meaning :
rd rs & const
Example :
andi $s1, $s2, 100 ; $s1 $s2 & 100
0
ori (logical or immediate)
Instruction Mnemonic :
ori rd, rs, const
; where rs, rd are registers, const is a 16-bit constant
Meaning :
rd rs | const
Example :
ori $s1, $s2, 100
; $s1
$s2 | 100
0
xori (logical Exclusive-or immediate)
●
●
●
Instruction Mnemonic :
xori rd, rs, const ;where rs, rd are registers, const is a 16-bit value
Meaning :
rd rs const
Example :
xori $s1, $s2, 100
; $s1
$s2
100
0
Uses for Logical Operators (1/3)
●
●
Note that anding a bit with 0 produces a 0 at
the output while anding a bit with 1 produces
the original bit.
This can be used to create a mask.
Example: andi $t0,$t0,0xFFF
1011 0110 1010 0100 0011 1101 1001 1010
mask: 0000 0000 0000 0000 0000 1111 1111 1111
●
The result of anding these:
0000 0000 0000 0000 0000 1101 1001 1010
●
mask last 12 bits
0
●
●
●
Uses for Logical Operators (2/3)
The second bitstring in the example is called a mask.
It is used to isolate the rightmost 12 bits of the first
bitstring by masking out the rest of the string (e.g.
setting it to all 0s).
Thus, the and operator can be used to set certain
portions of a bitstring to 0s, while leaving the rest
alone.
In particular, if the first bitstring in the above
example were in $t0, then the following
instruction would mask it:
andi
$t0,$t0,0xFFF
0
Uses for Logical Operators (3/3)
●
●
●
●
Similarly, note that oring a bit with 1 produces a 1 at
the output while oring a bit with 0 produces the
original bit.
This can be used to force certain bits of a string to 1s.
For example, if $t0 contains 0x12345678,
then after this instruction:
ori
$t0, $t0, 0xFFFF
… $t0 contains 0x1234FFFF (e.g. the highorder 16 bits are untouched, while the low-order
16 bits are forced to 1s).
0
Shift Operations
• Shifting is to move all the bits in a register left or right
• Shifts by a constant amount: sll, srl, sra
– sll/srl mean shift left/right logical by a constant amount
– The 5-bit shift amount field is used by these instructions
– sra means shift right arithmetic by a constant amount
– The sign-bit (rather than 0) is shifted from the left
0
Binary Multiplication
• Shift-left (sll) instruction can perform multiplication
– When the multiplier is a power of 2
• You can factor any binary number into powers of 2
– Example: multiply $s1 by 36
• Factor 36 into (4 + 32) and use distributive property of multiplication
– $s2 = $s1*36 = $s1*(4 + 32) = $s1*4 + $s1*32
0
Binary Multiplication
Multiply $s1 by 26, using shift and add instructions
●
Hint: 26 = 2 + 8 + 16
●
Multiply $s1 by 31, Hint: 31 = 32 – 1
0
●
●
●
●
●
●
●
●
●
Logical Shift Instructions (1/4)
Shift instruction syntax:
op dest,reg,amt
Op: operation name
Dest: register that will receive value
Reg: register with the value to be shifted
Amt: shift amount (constant < 32)
MIPS logical shift instructions:
sll (shift left logical): shifts left and fills emptied bits with
0s
srl (shift right logical): shifts right and fills emptied bits
with 0s
MIPS also has arithmetic shift instructions that fills with
the sign bit
0
●
●
●
Shift Instructions (2/4)
Shift Instruction Syntax:
1 2,3,4
where
1) operation name
2) register that will receive value
3) first operand (register)
4) shift amount (constant < 32)
MIPS shift instructions:
1. sll (shift left logical): shifts left and fills emptied bits
with 0s
2. srl (shift right logical): shifts right and fills emptied bits
with 0s
3. sra (shift right arithmetic): shifts right and fills emptied
bits by sign extending
0
Two Logic Instructions
●
Shift Left: sll $s1,$s2,2 #s1=s2<<2
●
Store in $s1 the value from $s2 shifted 2 bits to
the left, inserting 0’s on right; << in C
Before:
0000 0002hex
0000 0000 0000 0000 0000 0000 0000 0010two
After:
0000 0008hex
0000 0000 0000 0000 0000 0000 0000 1000two
What arithmetic effect does shift left have?
●
●
●
●
Shift Right: srl is opposite shift; >>
0
Shift Instructions (3/4)
●
Example 1: sra shift right arithmetic by 8 bits (note sign extend)
0001 0010 0011 0100 0101 0110 0111 1000
0000 0000 0001 0010 0011 0100 0101 0110
•
Example 2: shift right arithmetic by 8 bits (note sign extend)
1001 0010 0011 0100 0101 0110 0111 1000
1111 1111 1001 0010 0011 0100 0101 0110
0
●
●
●
Shift Instructions (4/4)
Since shifting may be faster than
multiplication, a good compiler usually notices
when C code multiplies by a power of 2 and
compiles it to a shift instruction:
a *= 8; (in C)
would compile to:
sll
$s0,$s0,3 (in MIPS)
# would multiply contents of $s0 by 8
Likewise, shift right to divide by powers of 2
remember to use sra
0
sll (shift left logical )
Instruction Mnemonic :
●
sll rd, rs, const
count)
W
;where rs, rd are registers, const is a 5-bit constant (shift
Meaning :
●
rd
●
H
rs << const
; logical shift left rs by const bits
Example :
sll $s1, $s2, 10 ; $s1
$s2 << 10
0
srl (shift right logical )
●
●
●
Instruction Mnemonic :
srl rd, rs, const ;where rs, rd are registers, const is a 5-bit
constant (shift count)
Meaning :
rd rs >> const
; logical shift right rs by const bits
Example :
srl $s1, $s2, 10
; $s1 $s2 >> 10
0
sra (shift right arithmetic )
●
●
●
Instruction Mnemonic :
sra rd, rs, const
;where rs, rd are registers, const is a 5bit constant (shift count)
Meaning :
rd rs >> const
; arithmetic shift right rs by const bits
Example :
sra $s1, $s2, 10
; $s1 $s2 >> 10
0
Shift Instructions
• Shifts by a variable amount: sllv, srlv, srav
– Same as sll, srl, sra, but a register is used for shift amount
0
sllv (shift left logical variable )
Instruction Mnemonic :
sllv rd, rs, rt ;where rs, rt, rd are registers, rt contains the shift count
Meaning :
rd rs << rt
; logical shift left rs by rt bits
Example :
sllv $s1, $s2, $s3
; $s1 $s2 << $s3
0
srlv (shift right logical variable)
Instruction Mnemonic :
srlv rd, rs, rt ;where rs, rt, rd are registers, rt contains the shift count
Meaning :
rd rs >> rt ; logical shift right rs by rt bits
Example :
srlv $s1, $s2, $s3 ; $s1 $s2 >> $s3
0
srav (shift right arithmetic variable )
Instruction Mnemonic :
srav rd, rs, rt ;where rs, rt, rd are registers, rt contains the shift count
Meaning :
rd rs >> rt ; arithmetic shift right rs by rt bits
Example :
srav $s1, $s2, $s3 ; $s1 $s2 >> $s3
0
0
0
MIPS Control Instructions
Book Section: 2.7
0
●
●
●
●
●
●
●
●
So Far...
All instructions so far only manipulate data…we’ve built a calculator.
In order to build a computer, we need ability to make decisions…
C (and MIPS) provide labels to support “goto” jumps to places in code.
Decision allows us to decide what to execute at run time rather than compile
time
C decisions are made using conditional statements within
If ,While , Do while, For
MIPS decisions making instructions are the conditional branches beq and
bne and j lable
In order to help conditional branches, make decisions concerning
inequalities, we introduce slt, slti, sltu,sltui
0
C Decisions: if Statements
●
●
●
●
●
2 kinds of if statements in C
if (condition) clause
if (condition) clause1 else clause2
Rearrange 2nd if into following:
if (condition) goto L1;
clause2;
goto L2;
L1: clause1;
L2:
Not as elegant as if-else, but same meaning
0
MIPS Decision Instructions
●
●
●
●
Decision instructions in MIPS causes control to branch to another place
Called conditional branches (Branch if a condition is met)
beq register1, register2, L1
beq is “branch if equal”
same meaning as: if (register1==register2) goto L1
bne register1, register2, L1
bne is “branch if not equal”
same meaning as: if (register1!=register2) goto L1
Can be used to implement complex control-flow constructs for high level
languages
0
MIPS Goto Instruction
●
In addition to conditional branches, MIPS has an
unconditional branch:
j
●
●
●
label
Called a Jump Instruction: jump (or branch) directly to the
given label without needing to satisfy any condition
Same meaning as (using C):
goto label
Technically, it’s the same as: beq
$0,$0,label
since it always satisfies the condition.
0
beq (branch on equal)
MIPS compare and branch instructions:
beq Rs,Rt,label
branch to label if (Rs == Rt)
bne Rs,Rt,label
branch to label if (Rs != Rt)
●
●
●
Instruction Mnemonic :
beq rd, rs, addr
;where rs, rd are registers, addr is the label of the
target location
Meaning : if (rd == rs ) then branch to label
i.e., goto PC + 4 + const*4 (i.e., PC = Updated PC + offset)
Example :
beq $s1, $s2, up
; if ($s1 = $s2) goto target location up
0
bne (branch on not equal )
●
●
●
Instruction Mnemonic :
bne rd, rs, addr
;where rs, rd are registers, addr is the label of the
target location
Meaning : if (rd != rs ) then branch to label
i.e., goto PC + 4 + const*4 (i.e., PC = Updated PC + offset)
Example :
bne $s1, $s2, loop ; if ($s1 != $s2) goto target location loop
0
●
Compiling C if into MIPS
C code
if (i == j) f=g+h;
else f=g-h;
Use mapping:
f: $s0, g: $s1, h: $s2, i: $s3, j: $s4
Final compiled MIPS code:
(true)
i == j
f=g+h
H
W
(false)
i == j?
i != j
f=g-h
Exit
beq $s3,$s4,True # branch i==j
is It
III
big
sub $s0,$s1,$s2 # f=g-h(false)
j Exit
# goto Exit
True: add $s0,$s1,$s2 # f=g+h (true)
Exit:
Note: Compiler automatically creates labels to handle decisions
(branches) Generally not found in HLL code.
0
Loops in C/Assembly (1/3)
There are three types of loops in C:
while
do… while
for
Each can be rewritten as either of the other two, so the method
used in the previous example can be applied to while and for
loops as well.
Key Concept: Though there are multiple ways of writing a
loop in MIPS, the key to decision making is conditional branch
0
Loops in C/Assembly (2/3)
Simple loop in C; A[] is an array of ints
do {
g = g + A[i];
j;
} while (i != h);
Rewrite this as:
Loop: g = g + A[i];
i = i + j;
if (i != h) goto Loop;
i=i+
0
●
●
●
Loops in C/Assembly (3/3)
Use this mapping:
g, h, i, j, base of A
$s1, $s2, $s3, $s4, $s5
Original code:
Loop: g = g + A[i];
i = i + j;
if (i != h) goto Loop;
Final compiled MIPS code:
Loop: sll $t1,$s3,2
# $t1= 4*i
add $t1,$t1,$s5
# $t1=addr A
lw $t1,0($t1)
# $t1=A[i]
add $s1,$s1,$t1
# g=g+A[i]
add $s3,$s3,$s4
# i=i+j
bne $s3,$s2,Loop
# goto Loop
# if i!=h
0
Compound Expression with AND
●
Programming languages use short-circuit evaluation
●
If first expression is false, second expression is skipped
0
Better Implementation for AND
The following implementation uses less code
Reverse the relational operator
Allow the program to fall through to the second expression
Number of instructions is reduced from 5 to 3
0
Compound Expression with OR
Short-circuit evaluation for logical OR
If first expression is true, second expression is skipped
Use fall-through to keep the code as short as possible
bgt, ble are pseudo-instructions that are translated by the assembler to real
instructions
0
●
●
Translating a WHILE Loop
Consider the following WHILE statement:
i = 0 ; while (A[i] != k) i = i+1;
Where A is an array of integers (4 bytes per element)
Assume address A, i, k in $s0, $s1, $s2, respectively
How to translate above WHILE statement?
xor $s1, $s1, $s1 # i = 0
or $t0, $s0, $0
# $t0 = address A
loop: lw $t1, 0($t0)
# $t1 = A[i]
beq $t1, $s2, exit # exit if (A[i]== k)
addiu $s1, $s1, 1 # i = i+1
sll $t0, $s1, 2
# $t0 = 4*i
addu $t0, $s0, $t0 # $t0 = address A[i]
j loop
exit: . . .
0
Using Pointers to Traverse Arrays
●
●
●
Consider the same WHILE loop:
i = 0; while (A[i] != k) i = i+1;
Where address of A, i, k are in $s0, $s1, $s2, respectively
We can use a pointer to traverse array A
Pointer is incremented by 4 (faster than indexing)
or $t0, $s0, $0
# $t0 = $s0 = addr A
j cond
# test condition
loop: addiu $s1, $s1, 1 # i = i+1
addiu $t0, $t0, 4 # point to next
cond: lw $t1, 0($t0)
# $t1 = A[i]
bne $t1, $s2, loop # loop if A[i]!= k
Only 4 instructions (rather than 6) in loop body
0
Copying a String
The following code copies source string to target string
Address of source in $s0 and address of target in $s1
Strings are terminated with a null character (C strings)
0
Summing an Integer Array
●
Assume $s0 = array address, $s1 = array length = n
0
Inequalities in MIPS
0
Inequalities in MIPS (3/3)
Now, we can implement <, but how do we implement >, ≤ and ≥ ?
We could add 3 more instructions, but:
MIPS goal: Simpler is Better
Can we implement ≤ in one or more instructions using just slt and
the branches?
What about >?
What about ≥?
0
Inequalities in MIPS (1/3)
Create a MIPS Inequality Instruction:
“Set on Less Than”
Syntax: slt reg1,reg2,reg3
Meaning:
reg1 = (reg2 < reg3);
if (reg2 < reg3)
reg1 = 1;
else reg1 = 0;
Same thing…
In computers, “set” means “set to 1”, “reset” means “set to 0”.
0
Inequalities in MIPS (2/3)
●
How do we use this? Compile by hand:
if (g < h) goto Less;
●
#g:$s0, h:$s1
Answer: compiled MIPS code…
slt $t0,$s0,$s1
# $t0 = 1 if g<h
bne $t0,$0,Less
# goto Less
# if $t0!=0
# (if (g<h)) Less:
●
Branch if $t0 != 0
●
Register $0 always contains the value 0, so bne and beq often
use it for comparison after an slt instruction.
●
A slt
(g < h)
bne pair means if(… < …)goto…
0
Compare : Set on Less Than Instructions
●
MIPS provides set on less than instructions
slt rd,rs,rt if (rs < rt) rd = 1 else rd = 0
sltu rd,rs,rt unsigned <
slti rt,rs, , imm16 if (rs < im16) rt = 1 else rt = 0
sltiu rt,rs, , imm16 unsigned <
0
Immediates in Inequalities
●
●
C
M
I
P
S
There is also an immediate version of ( set less than) slt
to test against constants: slti ( set less than immediate)
Helpful in for loops
if (g >= 1) goto Loop
Loop:
. . .
slti $t0,$s0,1
beq
# $t0 = 1 if
# $s0<1 (g<1)
$t0,$0,Loop # goto Loop
# if $t0==0
# (if (g>=1))
An slt
beq pair means if(… ≥ …)goto…
0
branch less than greater than or equal
●
●
●
●
●
●
●
●
●
●
●
●
There is no blt instead use
slt $s1, $s3, $s8
bne $s1, $s0, L
ble (branch if less than or equal)
slt $s1, $s8, $s5
beq $s1, $s0, L
bgt ( branch if greater than)
slt $s1, $s8, $s5
bne $s1, $s0, L
bge branch if greater than or equal
slt $s1, $s3, $s8
beq $s1, $s0, L
0
What about unsigned numbers?
●
●
Also unsigned inequality instructions:
sltu, sltiu
…which sets result to 1 or 0 depending on unsigned
comparisons
What is value of $t0, $t1?
($s0 = FFFF FFFAhex, $s1 = 0000 FFFAhex)
slt $t0, $s0, $s1
sign
sltu $t1, $s0, $s1
unsign
J
If
Bl
0
MIPS Signed vs. Unsigned – diff meanings!
●
●
●
●
MIPS Signed v. Unsigned is an “overloaded” term
Do/Don't sign extend
(lb, lbu)
Don't overflow
(addu, addiu, subu, multu, divu)
Do signed/unsigned compare
(slt, slti/sltu, sltiu)
0
slt (set less than)
●
●
●
Instruction Mnemonic :
slt rd, rs, rt ;where rs, rt, rd are registers,
Meaning :
if (rs < rt ) then rd = 1 else rd = 0
Example :
slt $s1, $s2, $s3 ; if ($s2 < $s3) then $s1=1 else $s1=0
0
●
●
●
slti (set less than immediate)
Instruction Mnemonic :
slti rd, rs, const
;where rs, rd are registers, const is a 16-bit constant
Meaning :
if (rs < const ) then rd = 1 else rd = 0
Example :
slti $s1, $s2, 100
; if ($s2 < 100) then $s1=1 else $s1=0
0
Comparison Instructions
sltu (set less than unsigned)
Instruction Mnemonic :
sltu rd, rs, rt
;where rs, rt, rd are registers,
Meaning :
if (rs < rt ) then rd = 1 else rd = 0
Example :
sltu $s1, $s2, $s3
; if ($s2 < $s3) then $s1=1 else $s1=0
0
sltiu (set less than immediate unsigned)
●
●
●
Instruction Mnemonic :
sltiu rd, rs, const ;where rs, rd are registers, const is a 16-bit constant
Meaning :
if (rs < const ) then rd = 1 else rd = 0
Example :
sltiu $s1, $s2, 100 ; if ($s2 < 100) then $s1=1 else $s1=0
0
●
Signed / Unsigned Comparisons can produce different results
Assume $s0 = 1 and $s1 = -1 = 0xffffffff
slt $t0,$s0,$s1 results in $t0 = 0
stlu $t0,$s0,$s1 results in $t0 = 1
0
SLT Instructions
0
Conditional Branch Instructions
●
●
MIPS compare to zero & branch instructions
Compare to zero is used frequently and implemented efficiently
bltz Rs,label
branch to label if (Rs < 0)
bgtz Rs,label
branch to label if (Rs > 0)
blez Rs,label
branch to label if (Rs <= 0)
bgez Rs,label
branch to label if (Rs >= 0)
No need for beqz and bnez instructions.
0
bgtz (branch on greater than zero)
●
Instruction Mnemonic :
bgtz rd, addr
;where rd is a register, addr is the label of the target
location
●
Meaning :
if (rd > 0 ) then branch to label
i.e., goto PC + 4 + const*4 (i.e., PC = Updated PC + offset)
Example :
bgtz $s1, up
; if ($s1 > 0) goto target location up
●
0
bltz (branch on less than zero)
●
●
●
Instruction Mnemonic :
bltz rd, addr
;where rd is a register, addr is the label of the target
location
Meaning :
if (rd < 0 ) branch to label
i.e., goto PC + 4 + const*4 (i.e., PC = Updated PC + offset)
Example :
bltz $s1, up
; if ($s1 < 0) goto target location up
0
blez (branch on less than or equal to zero)
●
●
●
Instruction Mnemonic :
blez rd, addr ; where rd is a register, addr is the label of the target
location
Meaning :
if (rd <= 0 ) branch to label
i.e., goto PC + 4 + const*4 (i.e., PC = Updated PC + offset)
Example :
blez $s1, loop
; if ($s1 <= 0) goto target location loop
0
bgez (branch on greater than or equal to zero)
●
●
●
Instruction Mnemonic :
bgez rd, addr
;where rd is a register, addr is the label of the target
location
Meaning :
if (rd >= 0 ) then branch to label
i.e., goto PC + 4 + const*4 (i.e., PC = Updated PC + offset)
Example :
bgez $s1, loop
; if ($s1 >= 0) goto target location loop
0
Branch Instructions
0
Branch Instructions
MIPS hardware does NOT provide instructions for …
blt, bltu branch if less than (signed/unsigned)
ble, bleu branch if less or equal (signed/unsigned)
bgt, bgtu branch if greater than (signed/unsigned)
bge, bgeu branch if greater or equal (signed/unsigned)
Can be achieved with a sequence of 2 instructions
• How to implement: blt $s0,$s1,label
• Solution:
slt $at,$s0,$s1
bne $at,$zero,label
• How to implement: ble $s2,$s3,label
• Solution:
slt $at,$s3,$s2
beq $at,$zero,lab
0
The C Switch Statement
220
179
c
bliss
0
MIPS Addressing Modes
●
Book Section 2.10
0
MIPS Addressing Modes
Register addressing (R-Type)
Where Operand is stored in a register
Base or displacement addressing (I-Type)
Where Operand at the memory location specified by a register
value plus a displacement given in the instruction;
Eg: lw, $t0, 25($s0)
Immediate addressing (I-Type)
Where Operand is a constant within the instruction itself
PC-relative addressing (I-Type)
Where The address is the sum of the PC and a constant in the
instruction
Pseudo-direct addressing (J-type)
Where the jump address is the 26 bits of the instruction
concatenated with the upper bits of the PC
New PC = {(upper 4 bits of PC+4), 26-bit constant, 00}
0
●
●
●
●
Register addressing
Source operands is in registers (R- type)
Since both data and instruction line in memory, they are accessed
by memory address
However, address space of 32 bit MIPS is too large to address as
immediate instruction format
So access to data and instruction is through several addressing
modes
0
Base Displacement
create memory address by adding a constant to a register value (Itype)
lw $s0, n($s1)
Offset here we do not need more than 16 bits immediate.
0
Branches: PC-Relative Addressing
●
Use I-Format
opcode
•
rs
rt
opcode specifies beq , bne:
immediat
e
beq $t2,$0,exit
bne $s3,$s2,Loop
• rs and rt specify registers to compare
• What can immediate specify?
•
Immediate is only 16 bits
•
PC (Program Counter) has byte address of current instruction being executed; 32-bit
pointer to memory
•
So immediate cannot specify entire address to branch to.
How do we usually use branches?
Answer: if-else, while, for
Loops are generally small: typically up to 50 instructions
Function calls and unconditional jumps are done using jump instructions (j and jal), not
the branches.
Conclusion: may want to branch to anywhere in memory, but a branch often changes PC by a
small amount
●
●
●
●
●
●
●
Branches: PC-Relative Addressing
Solution to branches in a 32-bit instruction: PC-Relative Addressing
Let the 16-bit immediate field be a signed two’s complement integer to be
added to the PC if we take the branch.
Now we can branch ± 215 bytes from the PC, which should be enough to
cover almost any loop.
Note: Instructions are words, so they’re word aligned (byte address is always
a multiple of 4, which means it ends with 00 in binary).
So the number of bytes to add to the PC will always be a multiple of 4.
So specify the immediate in words.
Now, we can branch ± 215 words from the PC (or ± 217 bytes), so we can
handle loops 4 times as large.
Branches: PC-Relative Addressing
●
●
●
●
●
●
Branch Calculation:
If we don’t take the branch:
PC = PC + 4
PC+4 = byte address of next instruction
If we do take the branch:
PC = (PC + 4) + (immediate * 4)
Observations
Immediate field specifies the number of words to jump, which is
simply the number of instructions to jump.
Immediate field can be positive or negative.
Pseudo-direct addressing (J-type)
Pseudo-direct addressing (J-type)
Where the jump address is the 26 bits of the instruction
concatenated with the upper bits of the PC
New PC = {(upper 4 bits of PC+4), 26-bit constant, 00}
0
Branch Example (1/3)
MIPS Code:
Loop:
beq
$9,$0,End
add
$8,$8,$10
addi $9,$9,-1
j
Loop
End:
beq branch is I-Format:
opcode = 4 (look up in table)
rs = 9 (first operand)
rt = 0 (second operand)
immediate = ???
●
●
●
●
Branch Example (2/3)
MIPS Code:
Loop:
beq
$9,$0,End
addi $8,$8,$10
addi $9,$9,-1
j
Loop
End:
Immediate Field:
Number of instructions to add to (or subtract from)
the PC, starting at the instruction following the
branch.
In beq case, immediate = 3
Branch Example (3/3)
●
MIPS Code:
Loop:
beq
addi
addi
j
$9,$0,End
$8,$8,$10
$9,$9,-1
Loop
End:
decimal representation:
4
9
000100 0100
1
0
0000
0
3
binary representation:
0000000000000011
●
Compiling C if into MIPS
C code
if (i == j) f=g+h;
else f=g-h;
Use mapping:
f: $s0, g: $s1, h: $s2, i: $s3, j: $s4
Final compiled MIPS code:
(true)
i == j
f=g+h
(false)
i == j?
i != j
f=g-h
Exit
beq $s3,$s4,True # branch i==j
sub $s0,$s1,$s2 # f=g-h(false)
j Fin
# goto Fin
True: add $s0,$s1,$s2 # f=g+h (true)
Fin:
Note: Compiler automatically creates labels to handle decisions
(branches) Generally not found in HLL code.
0
Loops in C/Assembly (1/3)
There are three types of loops in C:
while
do… while
for
Each can be rewritten as either of the other two, so the method
used in the previous example can be applied to while and for
loops as well.
Key Concept: Though there are multiple ways of writing a
loop in MIPS, the key to decision making is conditional branch
0
Loops in C/Assembly (2/3)
Simple loop in C; A[] is an array of integers
do {
g = g + A[i];
j;
} while (i != h);
Rewrite this as:
Loop: g = g + A[i];
i = i + j;
if (i != h) goto Loop;
i=i+
0
●
●
●
Loops in C/Assembly (3/3)
Use this mapping:
g, h, i, j, base of A
$s1, $s2, $s3, $s4, $s5
Original code:
Loop: g = g + A[i];
i = i + j;
if (i != h) goto Loop;
Final compiled MIPS code:
Loop: sll $t1,$s3,2
# $t1= 4*i
add $t1,$t1,$s5
# $t1=addr A
lw $t1,0($t1)
# $t1=A[i]
add $s1,$s1,$t1
# g=g+A[i]
add $s3,$s3,$s4
# i=i+j
bne $s3,$s2,Loop
# goto Loop
# if i!=h
0
New
MIPS Code Page 131
start
s
●
Instruction Format 15110 of
Emi
33 I
26301
dong
u
bit
egg
89
Id'd
I
1s
Is
I
If
tf
0
Name
Fields
Comments
Field size
6 bits
5 bits
5 bits
5 bits
5 bits
6 bits
All MIPS instructions 32 bits
R-format
op
rs
rt
rd
shamt
funct
Arithmetic instruction format
I-format
op
rs
rt
address/immediate
J-format
op
target address
Transfer, branch, imm. format
Jump instruction format
t.GS
J
0
Decoding Machine Language
●
Book page 134
0
Decoding Machine Language
How do we convert 1s and 0s to C code?
Machine language Assembly language C?
For each 32 bits:
Look at opcode: 0 means R-Format, 2 or 3 mean J-Format, otherwise IFormat
Use instruction type to determine which fields exist
Write out MIPS assembly code, converting each field to name, register
number/name, or decimal/hex number
Logically convert this MIPS code into valid C code
●
●
●
●
●
●
●
R
I
J
0
1, 4-31
2 or 3
rs
rt
rs
rt
rd
shamt
funct
immediate
target address
0
●
●
●
Decoding Example (1/5)
Here are six machine language instructions in
hexadecimal:
00001025hex
0005402Ahex
11000003hex
00441020hex
20A5FFFFhex
08100001hex
Let the first instruction be at address 4,194,304ten
(0x00400000hex)
Next step: convert hex to binary
0
Decoding Example (2/5)
The six machine language instructions in binary:
●
00000000000000000001000000100101
00000000000001010100000000101010
00010001000000000000000000000011
00000000010001000001000000100000
00100000101001011111111111111111
00001000000100000000000000000001
R
R
I
R
I
J
Next step: identify opcode and format
●
R
I
J
0
1, 4-31
2 or 3
rs
rt
rs
rt
rd
shamt
funct
immediate
target address
0
Decoding Example (3/5)
Next: fields separated based on format / opcode:
R
R
I
R
I
J
0
0
0
2
0
0
0
5
8
0
4
8
0
0
2
4
2
+
3
0
8
5
5
2
1,048,577
1
3
7
4
2
3
2
Next step: translate (disassemble) to MIPS instructions
0
Decoding Example (4/5)
MIPS assembly (Part 1):
Address
Assembly instructions
0x00400000
or
$2,$0,$0
0x00400004
slt
$8,$0,$5
0x00400008
beq
$8,$0,3
0x0040000c
add
$2,$2,$4
0x00400010
addi $5,$5,-1
0x00400014
j
0x100001 loop
What
Better solution: translate to more meaningful MIPS
instruction (fix the branch/jump, add labels and register
names)
0
Decoding Example (5/5)
●
●
MIPS Assembly (Part 2):
or
$v0,$0,$0
Loop:
slt
$t0,$0,$a1
beq
$t0,$0,Exit
$v0,$v0,$a0
$a1,$a1,-1
addi
j
add
Loop
Exit:
Next step: translate to C code (be creative!)
product = 0;
while (multiplier > 0) {
$v0: product
product += multiplicand;
$a0: multiplicand
multiplier -= 1;
$a1: multiplier
}
0
●
●
●
Revisit: lui
Example of lui
addi
$t0,$t0, 0xABABCDCD
lui
ori
add
$at, 0xABAB
$at, $at, 0xCDCD
$t0,$t0,$at
Wouldn’t it be nice if the translation can be
done automatically?
If number too big, then just automatically replace
addi with a sequence of lui, ori, add
0
Pseudoinstructions
pseudoinstruction
A MIPS instruction that doesn’t turn directly into a machine
language instruction, but into other MIPS instructions
Previous example: addi with a large immediate is
considered as a pseudoinstruction
The compiler / assembly programmer can write code
with pseudoinstructions
Assembler is responsible to break one pseudoinstruction
into several “real” MIPS instructions (Instructions implemented
by hardware)
This makes assembly programming much easier
0
Pseudo-instruction
If
●
Instructions to simplify task
●
Not implemented in Hardware
Understandable by the assembler
Convertible by the assembler into the machine language
equivalent
●
●
if
I
0
●
●
●
●
●
●
●
●
●
●
●
Example Pseudoinstructions
Register move
Format: move reg2,reg1
Equivalent to: add reg2,$zero,reg1
Load immediate
Format: li reg,value
If value fits in 16 bits: addi reg,$zero,value
Otherwise: lui reg, upper 16 bits of value
ori reg,$zero,lower 16 bits
Easy addition
addu
reg,reg,value # should be addiu
If value fits in 16 bits: addiu reg,reg,value
Otherwise: lui $at,upper 16 bits of value
ori $at,$at,lower 16 bits
addu reg,reg,$at
0
Pseudoinstruction Translation
Problem:
When breaking up a pseudoinstruction, the assembler
may need to use an extra register
If it uses any regular register, it’ll overwrite whatever
the program has put into it
Solution:
Reserve a register ($1, called $at for “assembler
temporary”) that assembler will use to break up
pseudo-instructions
Since the assembler may use this at any time, it’s not
safe to code with it
0
0
Questions?
0
Download