sections in this module | City
College of San Francisco - CS270 Computer Architecture Module: MIPS-II (Decisions) |
module list |
Problems
Problem One - comparing branch instructions
Let's compare these three techniques using a section of code from a simple example from a section of a sort function:Translating to gotos:
if
!(a < b) goto .L4 # (this is also if (a >= b)
goto .L4)
temp=b;
b = a;
a= temp;
.L4:
We will now translate this to MIPS code, with the following assumptions:
We will translate the code without using pseudoinstructions so we can see how many actual instructions there are. (We have added the lower 16-bits of the instruction's address to the listing)
address |
code using branch |
code using jump (j) |
code using jump reg (jr) |
0x401040 0x401044 0x401048 0x40104C 0x401050 0x401054 0x401058 0x40105C 0x401060 |
slt
$t2,$t0,$t1 beq $t2,$zero,.L4 move $t3,$t1 move $t1,$t0 move $t0,$t3 .L4: |
slt
$t2,$t0,$t1 bne $t2,$zero,.L5 j .L4 .L5: move $t3,$t1 move $t1,$t0 move $t0,$t3 .L4: |
slt
$t2,$t0,$t1 bne $t2,$zero,.L5 lui $at,0x0040 ori $t3,$at,0x1060 jr $t3 .L5: move $t3,$t1 move $t1,$t0 move $t0,$t3 .L4: |
You can see that the sequence using the branch instruction is shorter.
Last, let's go through the encoding of each of our branching instructions:
beq $t2,$zero,.L4
This is a regular I-type instruction with opc=4, rs=10 and rt=0.
The current PC is 0x401048 (the next instruction, remember?) and
the target is 0x401054, so it is 12 bytes, or three instructions,
away. Thus, imm = 3
op |
rs |
rt |
imm |
||||||||||||||||||||||||||||
0 | 0 | 0 | 1 | 0 | 0 | 0
|
1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
|
0 | 1 | 1 |
1 |
1 |
4 |
0 |
0 |
0 |
0 |
3 |
j .L4
The address of .L4 in the second sequence is 0x401058. Right-shifting this by 2 bits yields 0x100416. The opc is 2 and the remaining 26 bits of the instruction hold this word address:
op |
imm |
||||||||||||||||||||||||||||||
0 | 0 | 0 | 0 | 1 | 0 | 0
|
0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0
|
1 | 1 | 0 |
0 |
8 |
1 |
0 |
0 |
4 |
1 |
6 |
jr $t3
This is a modified R-type instruction where only the rs register is used. The opcode=0, the funct=8 and, in our case, rs=11:
op |
rs |
rt |
rd |
shamt |
funct |
||||||||||||||||||||||||||
0 | 0 | 0 | 0 | 0 | 0 | 0
|
1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1
|
0 | 0 | 0 |
0 |
1 |
6 |
0 |
0 |
0 |
0 |
8 |
Problem Two - outelement
Write a MIPS program to output A[i] from an int array A[5]
initialized with the values 4,-15,22,6,8. Your code should
request the index from the user using I/O, then output the array
element. If the index is less than 0 or greater than 4, output an
error message.
This program does not use a loop. Simply allow one attempt at accessing the array, then exit.
Step One
Write an algorithm for the program, using the following prototype
for retrieving an integer from the user and outputting an integer
value with a message
This corresponds to InputDialogInt and MessageDialogInt syscall. The error variable is the status returned by the Input syscall.
Step Two
Rewrite this algorithm using gotos and labels. Make a single
exit.
Finally, code this in MIPS. In this code we have intermixed the data and text segments much the way a compiler would generate them. This is not good coding style for a real assembler program, but it makes it easier to translate. We will make it prettier at the end.
#
# outelement.s
#
# int A[5] = {4,-15,22,6,8};
.data
.globl A
A: .word
4,-15,22,6,8
# int index;
.globl
index
index:
.space 4
# main() {
.text
.globl
main
main:
# index=get_int("Enter
index:");
li $v0,51
.data
.prompt: .asciiz "Enter
index:"
.align 2
.text
la $a0,.prompt
syscall
sw
$a0,index
# if (error == 0) goto
goodindex;
beq
$a1,$zero,.goodindex
# printf("Cannot get
index");
li $v0,55
.data
.msg1: .asciiz "Cannot
get index"
.align 2
.text
la $a0,.msg1
syscall
# goto doexit;
b
.doexit
# goodindex:
.goodindex:
# if (index < 0) goto
illegalindex;
lw $t0,index
blt
$t0,$zero,.illegalindex
# if (index > 4) goto
illegalindex;
li $t1,4
bgt
$t0,$t1,.illegalindex
# goto goodindex1;
b .goodindex1
# illegalindex:
.illegalindex:
# printf("index must be
between 0 and 4\n");
li $v0,55
.data
.msg2: .asciiz "index
must be between 0 and 4\n"
.align 2
.text
la $a0,.msg2
syscall
# goto doexit;
b .doexit
# goodindex1:
.goodindex1:
# message_int("A[index] =
",A[index]);
li $v0,56
sll $t0,$t0,2
la $t1,A
add $t1,$t1,$t0
lw $a1,0($t1)
.data
.msg3: .asciiz
"A[index] = "
.align 2
.text
la $a0,.msg3
syscall
# return
jr $ra # exit main() (normal
exit)
# exit;
# doexit:
.doexit:
li $v0,10
syscall
# }
Finally, merging the .data portions so that it is prettier, we get the final version:
Prev | This page was made entirely
with free software on linux: the Mozilla Project and Openoffice.org |
Next |