3. 5/20/2013
MIPS Instruction Set
• The instruction set contains all the instructions that run on a MIPS
processor
• This is a MIPS instruction
• add a, b, c
• This instruction will do: a = b + c
– The left side variable is the result
– The other two variables are the operands
• Now we want to add 4 numbers (b, c, d, e) and put the result in variable
a
There is no instruction to add b+c+d+e
• The assembly code is:
directly. Why? Because such instruction is
• add a, b, c
# a = b + c
hard to implement in hardware.
• add a, a, d
# add d to a
• add a, a, e
# add e to a; now a contains b+c+d+e
5
Reduced Instruction Set Computer (RISC)
• To add b,c,d,e we wrote a code of 3 instructions
• There is no one instruction in MIPS to do this
– Why? Because such instruction is hard to implement in hardware
• MIPS assembly language instructions style
– Each instruction does a simple task
– It’s easy to implement in hardware
– The instruction execution time is fast
MIPS code to make: a = b+c+d+e
add a, b, c
add a, a, d
add a, a, e
• This approach is called Reduced Instruction Set Computer
(RISC)
• MIPS is a RISC architecture (so is ARM)
Intel x86 architecture (IA‐32 and IA‐64) are Complex Instruction Set Computer (CISC)
since they have some complex instructions.
6
3
4. 5/20/2013
C to MIPS Assembly
• We have the C code:
a = b + c;
d = a – e;
• The compiler translates the C code to the following MIPS
assembly code:
add a, b, c
sub d, a, e
7
C to MIPS Assembly
• We have the C code:
f = (g + h) – (i + j);
• One possible assembly code generated by the compiler is:
add t0, g, h
# t0 is a temporary variable
add t1, i, j
# t1 is a temporary variable
sub f, t0, t1
When translating from C to assembly language,
there is more than one answer. (Note: f=g+h‐i‐j)
Another answer is:
add f, g, h
sub f, f, i
sub f, f, j
8
4
6. 5/20/2013
Variables in Memory
• The MIPS CPU has 32 registers only
– So we can have a limited amount of data on the CPU
• In C programming, we might declare an array of 100 words
– int n[100];
– These 100 integers are stored in memory (not on the CPU)
– If we need to use one element of the array in an operation (addition,
subtraction,…), we bring it to the CPU and put it in a register
– Then, the CPU can perform an operation on it
• After we get a result from a CPU instruction, we might need
to write it back to the array
– Then we take this result (from a register) and we write it back to the
memory (we put it in the array)
11
Movement of Data and Processing
Memory
CPU
(1) Move data to
registers
Large data
capacity
(2) Perform
operations on
the data
Limited storage
on the 32
Registers
(3) Write the result back to the memory
12
6
7. 5/20/2013
Moving Data between Memory and CPU
• MIPS has instructions to transfer data b/w memory and CPU
• They are called data transfer instructions
– A data transfer instruction has the address of the data in memory
• Transfer a data word (32 bits) from memory to CPU
– This is load instruction
– The instruction is called “load word” or lw for short
• Transfer a data word from the CPU to memory
– This is a store instruction
– The instruction is called “store word” or sw for short
• The address in MIPS is made of two parts:
– A base number, which is a number in a register
– An offset number, which is a constant number
The address is the addition of the base number and the offset number.
13
Memory in MIPS
• The memory is byte‐addressable
– Every byte has an address
0
1
2
3
These 4 bytes are a
word at address 0
4
5
6
7
Word at address 4
8
9 10 11 12 13 14 15
Word at address 8
Word at address 12
• In MIPS, a data unit is a word, which is 4 bytes
• The valid addresses in MIPS are multiples of 4
– MIPS addresses: 0, 4, 8, 12, 16, …, 256, …, 1024, …
14
7
9. 5/20/2013
Loading a Word from Memory
• We have the C code:
g = h + A[8];
• The variables g,h are associated with register $s1 and $s2
• The base address of the array A is in register $s3
– The address of the 1st element in A is equal to $s3
• The MIPS assembly code is:
lw $t0, 32($s3)
# Load A[8] in a temporary register
add $s1, $s2, $t0
Format of lw $t0, 32($s3)
‐The register on the left side ($t0) is where the word is loaded (from memory to $t0)
‐The address of the word in memory is 32+[the value in register $s3]
17
Storing a Word
• We have the C code:
A[12] = h + A[8];
• h is associated with $s2 and the base address of A is in $s3
• First we load A[8] into a register
• Then we add the variable h to it
• Then we take the result and store it in memory at address A[12]
• The assembly code is:
lw $t0, 32($s3)
add $t0, $s2, $t0
sw $t0, 48($s3)
# Load A[8] in register $t0
# Do $t0=h+A[8]
# Store the result in A[12]
Format of sw $t0, 48($s3)
‐The register on the left side ($t0) is the data that we will write to memory
‐The address in memory where we will write is 48+[the value in register $s3]
18
9
11. 5/20/2013
Encoding the Instruction
• MIPS has 32 registers; they are numbered from 0 to 31
• In the assembly language, we call them: $s0, $s1, … and $t0, $t1, …
– The mapping: $s0 to $s7 map to registers 16 to 23
– Mapping: $t0 to $t7 map to register 8 to 15
• The following instruction:
add $t0, $s1, $s2
• is broken down to the following fields
Register $s2
Register $s1
Register $t0
The 1st and last fields tell the CPU
that this is an “add” instruction
Unused in add
instruction
• The CPU looks at this instruction and knows what to do:
– It’s an add operation; add $s1 and $s2; put the result in $t0
21
Encoding the Instruction
add $t0, $s1, $s2
• The corresponding fields:
• In binary:
• The instruction is 32 bits
• Every instruction in MIPS is 32 bits
• In the computer it is stored as: 0000001000110010010000000010000
The first field (6 bits) is called “Operation Code” or “opcode”. This tells the CPU what
instruction it is. Arithmetic and logic instruction have the same opcode (000000). So,
the last 6 bits are used to differentiate between (add, sub, AND, OR, …)
22
11
12. 5/20/2013
Assembly Language vs. Machine Language
• An instruction written like this is called assembly language
add $t0, $s1, $s2
• When we write its binary encoding:
0000001000110010010000000010000
• We call it machine language
• If we have multiple of them, we call them machine code
• For our convenience, we might also write the instruction in
hexadecimal
Notice: A MIPS instruction is 32 bits. Also, a MIPS data word is 32 bits.
23
Instruction Format
• The fields are given names
• This is the format of the arithmetic and logic instruction (add, sub, mul, …,
AND, OR, …)
• We call these instructions: R‐type (since they operate on registers only)
• All of these instructions have the format
• The fields are:
–
–
–
–
–
All the R‐type instructions have the
opcode=000000. We differentiate
between them using the funct code.
A few slides back, we saw that for
“add”, funct=100000.
op: the operation of the instruction, or opcode
rs: register source operand
rt: second register source operand
rd: register destination; the result is stored in this register
shamt: shift amount; this field is used only in the “shift” instruction; for others it’s set
to: 00000
– funct: function code; when multiple instructions have the same opcode, this field tells
us which instruction it is
24
12
15. 5/20/2013
• The machine code is in binary
Example
• In binary…
29
Why is there no “subtract immediate”?
• Why MIPS assembly language doesn’t have a “subtract immediate”
instruction?
• This is the format of the I‐Type (including “addi”)
• The 16‐bit constant number is represented in 2’s complement
• If we need to subtract, we put a negative number
• On 16 bits and using 2’s complement representation
– We can write from: ‐32,768 to +32,767
30
15
16. 5/20/2013
Machine Code
• The machine code, encoded in binary, is sometimes called the binary
executable file
• This is what we get when we buy a program
• The seller keeps the source code (eg: C code…) to themselves since it’s
their intellectual property
– We have the right to use the software only
• The binary file runs on our computer
• Our CPU supports the instructions in the file
• For different platforms (Windows, Apple OS, Unix), the binary file is
different
• Intel plans their CPU architectures to be backward compatible
– I have a program that I bought for WinXP, I run it on Windows 7
– If they were not, the software I bought for my previous computers can’t be used
31
Logical Operations
• The table shows some of the logical operations that are supported in the
MIPS assembly language
• These operations allow us to access one or more bits inside the word
• Example: we need to read the upper (leftmost) 16 bits of a register
• We shift this register to the right by 16 bits
srl
$t0, $s0, 16
• If $s0 = 10101010 11111111 00000000 00110011
• Then, we have: $t0 = 00000000 00000000 10101010 11111111
32
16
17. 5/20/2013
Shift Left Logical (sll)
• This instruction shifts the number to the left
• The emptied bits on the right side are filled with 0
• This is a sll instruction:
sll $t2, $s0, 4
• Example:
Shift Right Logical (srl)
shifts the number to
the right. It puts 0 in
the emptied bits on the
left side.
– Register $s0 = 9. In binary, it is: 00000000 00000000 00000000 00001001
– After the instruction, $t2 = 00000000 00000000 00000000 10010000 = 144
• Shifting to the left by n bits is like multiplying the number by 2n
• The “sll” instruction has the format of R‐type
• This is the format for: sll $t2, $s0, 4
• Field rs is not used (we put 0), register $s0:16, and register $t2:10
33
AND operation
•
•
•
•
This is a bit‐by‐bit operation
AND can be used to read a field in a word
We want to read the rightmost 8 bits in a word
The word is: $s0 = 10101010 00001111 01100110 10011001
• First, we load a mask in a register
– $t0 = 00000000 00000000 00000000 11111111
• Then, we do:
and $t1, $s0, $t0
• Now, $t1 contains the lowermost 8 bits of register $s0
– We have: $t1 = 00000000 00000000 00000000 10011001
• We call this operation masking because we hid (or masked) the leftmost
24 bits of register $s0
34
17
20. 5/20/2013
Instructions for Making Decisions
• High‐level languages have if‐else
• In MIPS, we have “branch on equal” (beq)
beq $s0, $s1, L1
• If register $s0 is equal to register $s1, the code will go to the instruction
that is labeled L1
“beq” and “bne” are called
conditional branches since
they have a condition.
• In MIPS, we also have “branch on not equal” (bne)
bne $s0, $s1, L1
• If registers $s0 and $s1 are not equal, the code will jump to label L1
• MIPS also have the “jump” (j) instruction
j L1
• The code will jump to label L1
39
Example with Branching
• We have the C code:
if (i==j)
f = g + h;
else f = g – h;
• This is the translation in MIPS assembly language: (f,g,h,i,j are
mapped to registers $s0 through $s4)
bne i, j, Else
If the program doesn’t branch, it goes to the
next instruction.
add f, g, h
The same code using the register numbers:
j
Exit
bne
$s3, $s4, Else
Else: sub f, g, h
add
$s0, $s1, $s2
j
Exit
Exit:
Else:
Exit:
sub
$s0, $s1, $s2
40
20
21. 5/20/2013
Example with Branching
• We have the C code:
if (i==j)
f = g + h;
else f = g – h;
• This is the translation in MIPS assembly language: (f,g,h,i,j are mapped
to registers $s0 through $s4)
• We can write the code in a different way by using the “beq” instruction
beq i, j, Equal
sub
f, g, h
The same code using the register numbers:
j
Exit
beq
$s3, $s4, Equal
sub
$s0, $s1, $s2
Equal: add f, g, h
j
Exit
Exit:
Equal:
Exit:
add
$s0, $s1, $s2
41
Loop
• This C code increments the first 5 elements in the array by 1
i=0;
while (i <= 4)
array[i] = array[i]+1;
• The MIPS assembly translation is: (the base of the array is in $s0)
add
$t0, $s0, $zero # This is the address in the array to load; we will increment it.
# We could have used $s0, but we want to leave it unchanged.
addi
$t1, $s0, 20
# This is the cut off point to stop the loop; array[5]
Start:
beq
$t0, $t1, Exit
# $t0 will keep increasing until it reaches $t1
lw
$t2, 0($t0)
# Load the data in $t2
addi
$t2, $t2, 1
# Increment the data by 1
sw
$t2, 0($t0)
# Write the data back to the same address
addi
$t0, $t0, 4
# Increment the address to the next element
j
Start
# Jump back to the start
Exit:
42
21
23. 5/20/2013
Example
• Compare $s0 and $s1:
– Case 1: $s0 = $s1, then write 0 in register $s2
– Case 2: $s0 < $s1, then write 1 in register $s2
– Case 3: $s0 > $s1, then write 2 in register $s2
beq $s0, $s1, Case1
slt
$t0, $s0, $s1
bne $t0, $zero, Case2
addi $s2, $zero, 2
j
Exit
Case2:
addi $s2, $zero, 1
j
Exit
Case1:
add $s2, $zero, $zero
Exit:
# See if it’s Case1. If yes, jump to label “Case1”
# (If s0<s1t0=1), (If s0>=s1t0=0)
# If $t0 is 1, then it’s Case 2. Branch.
# It’s not Case 1 or 2, then it’s Case 3
# We go to “Exit” so we don’t do what’s below
# We go to “Exit” so we don’t do what’s below
45
Example
• Write a MIPS assembly language code to check if the content of $s0 is
even or odd
• If it’s even, write 0 in $s1. Otherwise, write 1 in $s1.
• Hint: a binary number that’s even ends with 0; if it’s odd, it ends with 1.
addi
and
$t0, $zero, 1
$t1, $t0, $s0
# This is a mask. It’s equal to 000…00001
# This preserves the rightmost bit of $s0
beq
addi
j
Even:
add
End:
$t1, $zero, Even
$s1, $zero, 1
End
# If $s0 is even, go to label “Even”
# If $s0 is odd, write 1 in $s1
# Skip the case “Even”
$s1, $zero, $zero
# Write 0 in $s1
46
23
27. 5/20/2013
Supporting Procedures
• The architecture provides the following features to support
procedures:
– Placing the parameters in a place where the procedure can access
them
– Transferring control to the procedure
– Reserving storage space that the procedure needs
– The procedure should then perform the required task
– Placing the result in a place where the calling program can access it
– Returning control to the point of origin
• Use of registers in MIPS
– $a0 to $a3: argument registers; these are used to pass parameters to
procedures
– $v0 and $v1: the procedure returns values in these registers
– $ra: ‘return address’ register is used to return to the calling code
53
“Jump‐and‐link” (jal) and “jump‐to‐register” (jr) Instructions
• These two instructions are used to jump to and return from
procedures
• The jump‐and‐link (jal) instruction jumps to a label at the start
of a procedure
– “jal” also saves the address of the instruction that is after “jal” in
register $ra (return address register). So, we get: $ra=PC+4
– When the procedure finishes, we return to the address in $ra to get
back to the main code
• The jump‐to‐register (jr) instruction jumps to the instruction
whose address is in the specified register
– At the end of a procedure, we put [jr $ra], so we jump back to where
we left off in the main code
54
27
29. 5/20/2013
Saved Registers vs. Temporary Registers
• The ‘main’ function in the assembly language program uses the
32 registers in MIPS to make the computations
• The ‘main’ function might call a procedure
• The procedure uses the same 32 registers of the CPU to make
the computations
• Potential problem: the procedure might delete some register
values that the main code needs to use in the future
• Solution:
– A procedure is allowed to overwrite the temporary registers: $t0 to $t7
– A procedure is not allowed to overwrite the saved registers: $s0 to $s7
– If a procedure needs to use one or more saved registers, it needs to
preserve their values before using them (save them on the stack)
57
The Stack
• The stack is a space in the memory where a procedure saves the
registers ($s0 to $s7) before it alters them
• The stack is a Last‐In First‐Out (LIFO) structure; it supports these
operations:
– Push: save a word on the stack
– Pop: retrieve a word from the stack
• The stack pointer ($sp) is a register that contains the memory address
of the last word that was pushed on the stack
• In MIPS, the stack grows towards smaller addresses
58
29
31. 5/20/2013
Example 2: Using the Stack
• A procedure uses $s0, $s1 and $s2
• It saves all of these on the stack and restores them at the end
of the procedure
addi $sp, $sp, ‐12 # Make space for 3 words on the stack
sw
$s0, 8($sp)
# Store the 1st register on the stack
sw
$s1, 4($sp)
# Store the 2nd register on the stack
sw
$s2, 0($sp)
# Store the 3rd register on the stack
…
<This is where the procedure code is written…>
…
lw
$s2, 0($sp)
# Retrieve the register value from the stack
lw
$s1, 4($sp)
lw
$s0, 8($sp)
addi $sp, $sp, 12 # We shrink the stack
jr
$ra
# Jump back to the calling code
61
Nested and Recursive Procedures
• A procedure that doesn’t call another procedure is called a
leaf procedure
• A procedure that calls another procedure is called a nested
procedure
• A procedure that calls itself is called a recursive procedure
int bigger(int x, int y) {
if(x > y)
return x;
else return y;
}
int fn1(int x, int y) {
if(x>0 && y>0)
return avg(x,y);
else return y;
}
int factorial(int n) {
if(n<1)
return 1;
else return (n*factorial(n‐1));
}
This is a leaf function. It
doesn’t call any other
function.
This is a nested function.
It calls another function
(the function “avg”).
This is a recursive function. It
calls itself.
62
31
32. 5/20/2013
Recursive Procedure
• A procedure that calls itself
• Some problems are easy to program via a recursive algorithm
– A problem that can be reduced into a similar problem of smaller size
•
•
•
•
Computing the factorial of an integer
n! = n.(n‐1).(n‐2)…3*2*1
Eg: 4! = 4*3*2*1 = 24
By definition 0! = 1
• Observe: n! = n * (n‐1)!
– We reduced the problem (finding n!) into a smaller problem of
smaller size (finding (n‐1)!)
63
Factorial Algorithm
• This is the C code for a recursive factorial algorithm
int factorial(int n) {
if (n<1)
// By definition 0!=1
return 1;
else
return (n*factorial(n‐1));
// Recursive call
}
• We don’t want the recursive function to keep calling itself
infinitely
• There is one (or more) trivial case or base case
– We know the answer of the trivial case so we don’t have to make
another recursive call
– Here, the trivial case is factorial(0)=1
64
32
33. 5/20/2013
int factorial(int n) {
if (n<1)
// By definition 0!=1
return 1;
else return (n*factorial(n‐1)); // Recursive call
}
• We call this function with n=3
–
–
–
–
–
–
–
It will return 3 * factorial(2)
There will be another call with n=2
It will return 2 * factorial(1)
There will be another call with n=1
It will return 1 * factorial(0)
There will be another call with n=0
It will return 1
• Now we know factorial(0)=1,
we substitute in
[1*factorial(0)]=1
• Now we know factorial(1)=1,
we substitute in
[2*factorial(1)]=2
• Now we know factorial(2)=2,
we substitute in
[3*(factorial(2)]=6. This is the
answer.
When the recursive algorithm is running, the computations will stack up
(left side). Once we reach to the trivial case, we go up the stacked things
and combine the solutions to get the final answer (right side).
108:
112:
116:
120:
…
...
300:
304:
308:
312:
316:
…
jal
sw
…
Procedure1
$v0, 0($s1)
It saves $ra=116
Procedure1:
add
$t0, $a0, $a1
…
jal
Procedure1
…
jr
$ra
# Jump to procedure
# Store the result
65
How do we support
recursive procedures in
MIPS?
$ra becomes equal to 312
(the old value=116 is lost)
# Recursive call
What’s wrong with the code above?
The main function calls Procedure1 using the ‘jal’ instruction
Therefore, the return address is saved; $ra=116
Procedure1 is a recursive function and calls itself using ‘jal’
Therefore, a new value is saved in the return address register; $ra=312
We’ve lost the original $ra value (116) and we can’t go back to the main function
Solution: In recursive functions, before ‘jal’ is used, the value of $ra is saved on the stack
This means Procedure1 should have saved $ra on the stack before using ‘jal’ to call itself
66
33
40. 5/20/2013
String Copy Function (strcpy)
• This function in C language allows us to copy one string to another
• In C, the string is terminated by the NULL character (value=0)
• In the code below, we manually copy the NULL character at the end of
the string
void strcpy (char x[], char y[]) {
int i;
i=0;
while(y[i] != ‘0’) {
x[i] = y[i];
i = i + 1;
}
x[i] = y[i]; // Copy the Null=0 character
}
79
# Copy y into x; base address of x and y are in $a0 and $a1, respectively
strcpy:
addi $sp, $sp, ‐4
# Adjust the stack for 1 more word
sw
$s0, 0($sp)
# We will use $s0, so we save it on the stack
add
$s0, $zero, $zero
Start:
add $t1, $s0, $a1
lb
$t2, 0($t1)
# This will hold the index i
# $t1 has the address of y[i]
add
sb
$t3, $s0, $a0
$t2, 0($t3)
# $t3 has the address of x[i]
beq
$t2, $zero, End
# Is the array done?
addi
j
$s0, $s0, 1
Start
# Notice here, we increment the index by 1
End:
lw
addi
jr
$s0, 0($sp)
$sp, $sp, 4
$ra
# Restore the value of $s0 from the stack
# Readjust the stack pointer
80
40
41. 5/20/2013
Unicode Letter Representation
•
•
•
•
Unicode uses 16 bits to represent a character
Therefore, it can represent 216 = 65,536
Unicode represents multiple languages
Java uses Unicode to represent letters
• MIPS provides the following instructions
• Load half (lh):
– Load 16 bits from the memory to register
• Store half (sh):
– Store 16 bits from a register to the memory
81
Word Alignment
• MIPS keeps the word addresses aligned to multiples of 4
• The valid word addresses are multiples of 4
• If there is one character variable encoded in ASCII (char c;)
– It needs 1 byte but MIPS allocates 4 bytes for it to keep words
aligned, as in figure below (‘A’). Therefore, 3 bytes are wasted.
• But if it’s an array of characters (string), then there can be 4
characters in a MIPS word
– In this case, the memory is used efficiently
32‐bit number @ address100
10101010 00000000 00001111 11111111
8‐bit character @ address104
‘A’
unused
unused
unused
32‐bit number @ address108 00001111 00001111 11110000 10101010
4‐character string @add. 112
‘A’
‘B’
‘C’
‘D’
82
41
42. 5/20/2013
Loading a Number in a Register
• We can use the ‘addi’ instruction
addi $s0, $zero, <number>
• The format of addi is:
• With ‘addi’, we can load at most a 16‐bit number in the
register
• What if we need to load a 32‐bit number in a register?
– Two instructions are used to do this
83
Loading a 32‐bit Number in a Register
• Load upper immediate (lui) instruction loads a 16‐bit number in
the left half of a register; the right half is filled with zeros
• Our goal is to load in $s0: 0000000011111111 0101010101010101
• Load the leftmost 16 bits: lui
$s0, 0000000011111111
• After this: $s0=0000000011111111 0000000000000000
• Now, the lower part of $s0 is loaded
• We can do:
ori $s0, $s0, 0101010101010101
16‐bit extended to 32 bits
0000000000000000 0101010101010101
OR
$s0
0000000011111111 0000000000000000
• Now: $s0 = 0000000011111111 0101010101010101
84
42
44. 5/20/2013
Jump Instruction Format
• It is the J‐type format,
Syntax: j
Label
• The address is designated by 26 bits
• How do we get the actual 32‐bit address of the instruction
we’re jumping to?
PC+4[31:28]
26‐bit number in the ‘j’ instruction
Leftmost 4 bits of PC+4. We jump to
somewhere that’s somewhat close to the
current instruction. This is because all of a
program’s code is stored in one memory
space.
00
MIPS addresses are multiples of 4. Every
address written in binary ends with ’00’.
So when we encode the ‘j’ instruction, we
remove ’00’ and then we add it later. This
allows us a larger jump range.
87
Example
• Find the jump address. Assume that PC=24
00 00000000 00000000 00001011
• PC+4=28=0000000000000000 0000000000011100
– Take the leftmost 4 bits of PC+4 0000
• The jump address is:
PC+4[31:28]
26‐bit number in the j instruction
00
0000 00000000000000000000001011 00
88
44
45. 5/20/2013
Branch Instruction Format
• Branch‐on‐equal (beq);
Syntax: beq $s0, $s1, Exit
4
• The branch address is:
PC + 4 + SignExtendTo32[ShiftLeftBy2(16‐bit number)]
• This is the procedure:
– Take the 16‐bit number, add ’00’ on the right side (shift left by 2)
– The ‘00’ were omitted in the encoding since all instruction addresses
end with ’00’ (omitting the ’00’ gives us a longer range in the branch)
• Sign extend the 18‐bit number above to 32 bits
• Add this to PC+4
Why do we add to PC+4 not to PC? Because when the CPU is executing
instructions, it automatically updates PC to PC+4. So by the time we
decode the ‘beq’ instruction, PC has been incremented by 4.
89
Branch Instruction Format
• Branch‐on‐equal (beq);
4
Syntax: beq $s0, $s1, Exit
00000000 00000111
• The branch is taken when the two registers are equal
• Find the branch address
• Assume that PC=20
• First, we shift the 16‐bit number left by 2 bits
– It becomes: 00000000 0000011100 equal to: 28
• Sign‐extend to 32 bits: 000…0000000011100 (still equal to 28)
• PC+4 = 24. We add 28 to it, the branch address is 52
• On 32 bits, it is: 00000000 00000000 00000000 00110100
90
45
46. 5/20/2013
• Translate the MIPS assembly code below into machine code
• Also, fill the branch and jump addresses assuming that the
code is stored in the memory starting at address 80,000
80,000
80,004
80,008
80,012
80,016
80,020
80,024
“bne $t0, $s5, Exit” branches from address 80,012 to address 80,024
Branch address = PC+4+offset offset = 80,024–80,012–4 = 8
Instead of putting 8 (1000) in the instruction, we drop the ’00’ from the
right side
So we store ’10’(binary) in the instruction over 16 bits
The values of “bne” instruction fields are below in decimal
5
8
21
2
91
80,000
80,004
80,008
80,012
80,016
80,020
80,024
“j Loop” instruction jumps to address 80,000
This is how we find the 26‐bit field in ‘j’ instruction
PC+4[31:28]
26‐bit number in the j instruction
00
Jump address is: 80,000 00000000 000000001 00111000 10000000
The right ’00’ are dropped; the upper 4 bits aren’t included
The 26‐bit field in the instruction is: 0000 00000001 00111000 100000,
which is 20,000 in decimal
2
20,000
92
46
48. 5/20/2013
MIPS Addressing Modes Summary
• “Addressing mode” is how the instruction gets its operands
• Register addressing:
– The operand is taken from the register
(eg: add $t0, $t1, $t2)
• Base or displacement addressing:
– We add the base (of an array) to an offset to find the data’s address
in memory
(eg: lw $t0, 0($s1))
• Immediate addressing:
– The operand is a constant encoded in the instruction (addi $t0,$t1,4)
• PC‐relative addressing:
– In the branch instructions (beq, bne), the offset is added to the PC
• Pseudodirect addressing:
– In the jump address, almost all of the address is in the instruction (26
bits out of 32 bits are encoded in the instruction)
95
The Addressing Modes
96
48