PPMIPS
PPMIPS
PPMIPS
Lesson #1
Course Description
Basic computer organization concepts such as registers, the ALU, data path, and random access memory (RAM). The use of pseudocode to develop and document algorithms at the register level. Number systems and the rules for arithmetic. Passing parameter to functions using the stack. Assemblers and linking editors. Modular program design and development.
Introduction
Basic Computer Organization Machine Language
Assembly Language
MIPS
MIPS
PowerPC
DataPath Diagram
Prog ram Counter (PC) Cache Memo ry Instruction Register Out Rs ALU
Address
Co ntrol Lo gi c
Rd
Rt
Number
Value
Name
$zero $at $v0 $v1 $a0 $a1 $a2 $a3 $t0 $t1 $t2 $t3 $t4
Register File
0 1 2 3 4 5 6 7 8 9 10 11 12
13
14 15 16 17 18 19 20 21 22 23 24
$t5
$t6 $t7 $s0 $s1 $s2 $s3 $s4 $s5 $s6 $s7 $t8
Callee-Saved Registers Use these registers for values that must be maintained across function calls.
Comments
# $a0 = 0 # $t0 = 99
add $a0, $a0, $t0 addi $t0, $t0, -1 bnez $t0, loop li $v0, 1 syscall li $v0, 10 syscall
# $a0 = $a0 + $t0 # $t0 = $t0 - 1 # if ($t0 != zero) branch to loop # Print the value in $a0
# Terminate Program Run
Rs
5
Rt
5
Rd
5
Code
6
Immediate Format
Op-Code 6 Rs 5 Rt 5 16 - Bit Immediate Value 16
Jump Format
Op-Code 6 26 Bit Current Segment Address 26
Main Memory
Op-Code 13
Rs 0 Addre ss 0 1 2 3
Rt 8
Rd 0 na me
Immediate 9
$zero $a t $v 0 $v 1 $a 0 $a 1 $a 2 $a 3 $t0 $t1 $t2 $t3 $t4 $t5 $t6 $t7 $s 0 $s 1 $s 2 $s 3 $s 4 $s 5 $s 6 $s 7 $t8 $t9 $k 0 $k 1 $gp Rt 7 4 Rs 0 ALU
Control Logic
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 26 28 29 30 31
40 000 0 48
Re g. File
lw or sw
beqz
Address = Rs + Offset sw lw
R-Type
Memory[Address] = Rt
Pseudo Instructions
Load Address Load Immediate Move Multiply Divide Remainder Negate la $s0, table li $v0, 10 move $t8, $sp mul $t2, $a0, $a1 div $s1, $v1, $t7 rem $s2, $v1, $t7 neg $s0, $s0
: Constant Zero : Returned values from functions : Arguments passed to functions : Temporary registers (functions) : Saved registers (main program) : Stack Pointer : Return address
Lesson #2
Exercises Chapter 1
1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 Explain the difference between a register and the ALU. Explain the difference between Assembly Language and Machine Language. Explain the difference between Cache Memory and the Register File. Explain the difference between the Instruction Register and the Program Counter. Explain the difference between a Buss and a control line. Identify a kitchen appliance that contains a finite state machine. If a 500 MHz machine takes one-clock cycle to fetch and execute an instruction, then what is the instruction execution rate of the machine? How many instructions could the above machine execute in one minute? Lets suppose we have a 40-year-old computer that has an instruction execution rate of one thousand instructions per second. How long would it take in days, hours, and minutes, to execute the same number of instructions that you derived for the 500 MHz machine? What is an algorithm?
1.10
Lesson #3
Pseudocode
Using Pseudocode to Document a MIPS Assembly Language Program
When documenting an algorithm in a language such as Pascal or C, programmers use descriptive variable names such as: speed, volume, size, count, amount, etc. After the program is compiled, these variable names correspond to memory locations. To efficiently execute code, a compiler will attempt to keep the variables that are referenced most often in processor registers because access to a variable in a processor register is much faster than access to memory. MIPS has 32 processor registers. The names used to reference these registers are defined in Figure 2.1 on page 4 in the textbook.
As an assembly language programmer you must take maximum advantage of the processor registers. For example, you may have a value in register $s0 corresponding to speed, a value in register $s1 corresponding to volume, a value in register $s2 corresponding to size, and a value in register $t3 corresponding to count.
When using pseudocode to document an assembly language program, you will be expected to use the names of the registers you intend to use in the assembly language code. It is advisable to create a cross reference table between the processor register name and what it is being used for in the program .
We use register names in pseudocode because the purpose of the pseudocode is to document an assembly language program.
Unless you identify the registers being used, the pseudocode is quite limited in terms of having any correspondence to the assembly language code. You will also find that as soon as you are able to develop the pseudocode in this format it is a very simple process to translate pseudocode into assembly language code.
Pseudocode for assembly language programs will have the appearance of Pascal or C in terms of control structures and arithmetic expressions, but descriptive variable names will usually only appear in the LOAD ADDRESS (la) instruction where there is a reference to a symbolic memory address. In assembly language you define and allocate space for variables in the data segment of memory using assembler directives such as .word and .space. You will find that all of the MIPS instructions require the use of processor registers. When writing pseudocode you should specify the processor registers you are planning to use to accomplish the task.
Now for an example, let us suppose that we want to write an assembly language program to find the sum of the integers from 1 to N. In other words do the following: 1 + 2 + 3 + 4 + 5 + 6 + 7 + ....+ N, where N is an input value.
On the next slide you will see a pseudocode description of the algorithm and following that the corresponding assembly language program, where processor register $t0 is used to accumulate the sum, and processor register $v0 is used as a loop counter. Use a word processor to create the following program file. Be sure to save as text only. Next, load the program into SPIM. Run the program and experiment with the different features of the MIPS simulator. ( For example: Single Step) Read the help file for a description of how to use the simulator.
main:
loop:
.data .asciiz .asciiz .asciiz .globl .text li la syscall li syscall blez li add addi bnez
"\n\n Please Input a value for N = " " The sum of the integers from 1 to N is " "\n **** Adios Amigo - Have a good day **** " main
$v0, 4 $a0, prompt $v0, 5 $v0, done $t0, 0 $t0, $t0, $v0 $v0, $v0, -1 $v0, loop # system call code for print_str # load address of prompt into a0 # print the prompt message # system call code for read_int # reads a value of N into v0 # if ( v0 < = 0 ) go to done # clear $t0 to zero # sum of integers in register $t0 # summing in reverse order # branch to loop if $v0 is !=
zero
# system call code for print_str # load address of message into $a0 # print the string # system call code for print_int # a0 = $t0 # prints the value in register $a0
done:
li la syscall
li syscall
# system call code for print_str # load address of msg. into $a0 # print the string
# terminate program # return control to
$v0, 10
system MUST HAVE A BLANK LINE AT THE END OF THE TEXT FILE
$t8, else # if ($t8 is > or = zero) branch to else $s0, $zero, $t8 # $s0 gets the negative of $t8 $t1, $t1, 1 # increment $t1 by 1 next # branch around the else code
$s0, $t8, 0 $t2, $t2, 1 # $s0 gets a copy of $t8 # increment $t2 by 1
break:
Here is a translation of the above while pseudocode into MIPS assembly language code. li $v0, 1 # Load $v0 with the value 1 loop: bgeu $a1, $a2, done # If( $a1 >= $a2) Branch to done lb $t1, 0($a1) # Load a Byte: $t1 = mem[$a1 + 0] lb $t2, 0($a2) # Load a Byte: $t2 = mem[$a2 + 0] bne $t1, $t2, break # If ($t1 != $t2) Branch to break addi $a1, $a1, 1 # $a1 = $a1 + 1 addi $a2, $a2, -1 # $a2 = $a2 - 1 b loop # Branch to loop break: li $v0, 0 # Load $v0 with the value 0 done:
li
$a0, 0
# $a0 = 0
li
loop: add addi bgtz
$t0, 10
$a0, $a0, $t0 $t0, $t0, -1 $t0, loop
Lesson #4
# Default for less than one # Default for greater than 3 # Create a word offset # Form a pointer into jumptable # Load an address from jumptable # Go to specific case
case2:
sll b case3: sll done:
$s1, main
$v0, 10
Exercises Chapter 2
2.1 (a) Using Appendix A, translate each of the following pseudocode expressions into MIPS assembly language: t3 = t4 + t5 t6;
(b)
(c) (d) (e) (f) (g) (h)
s3 = t2 / (s1 54321);
sp = sp 16; cout << t3; cin >> t0; a0 = &array; t8 = Mem(a0); Mem(a0+ 16) = 32768;
(i)
(j) (k) (l)
add $t3, $t4, $t5 sub $t3, $t3, $t6 addi $s3, $s1, 54321 div $t2, $s3 mflo $s3 addi $sp, $sp, -16 move $a0, $t3 li $v0, 1 syscall li $v0, 5 syscall move $t0, $v0
la lw
Exercises Chapter 2
(m) (n) (o) (p) (q) (r) (s) t0 = 2147483647 - 2147483648; s0 = -1 * s0; s1 = s1 * a0; s2 = srt(s02 + 56) / a3; s3 = s1 - s2 / s3; s4 = s4 * 8; s5 = * s5;
2.2 Analyze the assembly language code that you developed for each of the above pseudocode expressions and calculate the number of clock cycles required to fetch and execute the code corresponding to each expression. (Assume it takes one clock cycle to fetch and execute every instruction except multiply and divide, which require 32 clock cycles and 38 clock cycles respectively.) 2.3 Show how the following expression can be evaluated in MIPS assembly language, without modifying the contents of the s registers: $t0 = ( $s1 - $s0 / $s2) * $s4 ;
Exercises Continued
2.2 Analyze the assembly language code that you developed for each of the above pseudocode expressions and calculate the number of clock cycles required to fetch and execute the code corresponding to each expression.
(Assume it takes one clock cycle to fetch and execute every instruction
except multiply and divide, which require 32 clock cycles and 38 clock cycles respectively.) 2.3 Show how the following expression can be evaluated in MIPS assembly language, without modifying the contents of the s registers: $t0 = ( $s1 - $s0 / $s2) * $s4 ;
Lesson #5
MIPS
MIPS
Rs
5
Rt
5
Rd
5
Code
6
Immediate Format
Op-Code 6 Rs 5 Rt 5 16 - Bit Immediate Value 16
Jump Format
Op-Code 6 26 Bit Current Segment Address 26
lw or sw
beqz
Address = Rs + Offset sw lw
R-Type
Memory[Address] = Rt
Comments
# $a0 = 0 # $t0 = 99
add $a0, $a0, $t0 addi $t0, $t0, -1 bnez $t0, loop li $v0, 1 syscall li $v0, 10 syscall
# $a0 = $a0 + $t0 # $t0 = $t0 - 1 # if ($t0 != zero) branch to loop # Print the value in $a0
# Terminate Program Run
Number Systems
Introduction Polynomial Expansion Binary Numbers Hexadecimal Numbers Twos Complement Number System Arithmetic & Overflow Detection American Standard Code for Information Interchange (ASCII)
496 = 4 x 10 + 9 x 10 + 6 x 10
10
00101101 = 1 x 2 + 0 x 2 + 1 x 2 + 1 x 2 + 0 x 2 + 1x 2
2
A Faster Method
00101101 = 45
45 Remainder 22 1 11 0 5 1 2 1 1 0 0 1
101101
To represent binary values in the positive and negative domains we use the Twos Complement Number System
Here is the polynomial expansion of a twos complement number 8-bit binary number N:
N=
To find the value minus 26 in binary we perform the twos complement operation on 00011010.
Scan the binary number from right to left leaving all least significant zeros (0) and the first one (1) unchanged, and then complementing the remaining digits to the left: 11100110 The result is the value minus 26 in binary.
Overflow Occurred
Overflow
0000 1111 0 1110 -2 1101 -3 -1 1 2 0011 3 0010 0001
1100
-4
0100
-5 1011 -6 5 0101
6 1010 -7
-8 0111
7
0110
1001
1000
Binary Arithmetic
in the Twos Complement Number System
Here is a subtraction example where we assume we are limited to 8 binary digits. To subtract in binary we always add the twos complement of the subtrahend. 01000100 = 01000100 -00111100 = +11000100 00001000 = 00001000 = 68 60 8
11101000 -00010011
Sign Extension
The value 43 as an 8-bit binary number is: 11010101 The value 43 as an 32-bit binary number is: 11111111111111111111111111010101 In Hexadecimal 43 appears as: 0xFFFFFFD5
###############################################
The value 68 as an 8-bit binary number is: 01000100 The value 68 as an 32-bit binary number is: 00000000000000000000000001000100 In Hexadecimal 68 appears as: 0x00000044
0x 3 C 8 F 7 E
Lesson #6
E2.5
Convert the decimal number 35 to an 8-bit binary number. Convert the decimal number 32 to an 8-bit binary number.
Exercises
00100011 00100000
Using the double and add method convert 00010101 to a decimal number. Using the double and add method convert 00011001 to a decimal number.
21
25
Explain why the Least Significant digit of a binary number indicates if the number is odd or even. LSD is a 1 Convert the binary number 00010101 to a hexadecimal number. Convert the binary number 00011001 to a hexadecimal number. 0x15 0x19 21 25
3.8
3.9 3.10
Convert the decimal number -35 to an 8-bit twos complement binary 11011101 number.
3.11 3.12
Convert the decimal number -32 to an 8-bit twos complement binary number. 11100000 Assuming the use of the twos complement number system find the equivalent decimal values for the following 8-bit binary numbers: -127 (a) 10000001 -1 (b) 11111111 80 (c) 01010000 -32 (d) 11100000 -125 (e) 10000011 Convert the base 8 number 204 to decimal 132 Convert the base 7 number 204 to decimal 102 Convert the base 6 number 204 to decimal 76 Convert the base 5 number 204 to decimal 54 Convert the base 10 number 81 to a base 9 number. 100
Exercises
3.13 3.14
3.15
3.16 3.17
3.18
For each row of the table below convert the given 16 bit number to eachExercises of the other two bases, assuming the twos complement number system is used. 16 Bit Binary Hexadecimal Decimal
1111111100111100
0xFF88
-128 1111111111111010
0x0011
-25 3.19 You are given the following two numbers in twos complement representation. Perform the binary addition and indicate if there is signed overflow. __ Explain Why: 01101110 00011010 10001000
Yes overflow occurred Sign of the result is different from the operands
Exercises
3.20 You are given the following two numbers in twos complement representation. Perform the binary subtraction and indicate if there is signed overflow. ______ Explain Why:
11101000 -00010011
No Overflow
3.21
FF88 Sign extend the 8 bit hex number 0x88 to a 16 bit number. 0x_________
3.22
The following subtract instruction is located at address 0x00012344. What are the two possible values for the contents of the PC after the 00012340 0001234C branch instruction executed? 0x_____________ 0x ____________ This branch instruction is described in Appendix C. loop: addi sub bne $t4, $t4, -8 $t2, $t2, $t0 $t4, $t2,loop
Exercises
3.23 You are given the following two 8-bit binary numbers in the twos complement number system. What values do they represent in decimal? -108 44 X = 10010100 = __________ Y = 00101100 = __________ 2 10 2 10 Perform the following arithmetic operations on X and Y. Show your answers as 8-bit binary numbers in the twos complement number system. To subtract Y from X, find the twos complement of Y and add it to X. Indicate if overflow occurs in performing any of these operations. X+Y 10010100 00101100 11000000 X-Y 10010100 +11010100 01101000 Y-X 00101100 +01101100 10011000
Exercise 3.24
The following code segment is stored in memory starting at memory location 0x00012344. What are the two possible values for the contents of the PC after the branch instruction has executed? 0x__________ 00012344 0x ____________ 00012354 Add in line pseudocode to describe each instruction.
# # # #
Lesson #7
Text Segment
[0x00400020] [0x00400024] [0x00400028] [0x0040002c] [0x00400030] [0x00400034] [0x00400038] [0x0040003c] [0x00400040] [0x00400044] [0x00400048] [0x0040004c] [0x00400050] [0x00400054] 0x34020004 ori $2, $0, 4 ; 34: li $v0, 4 0x3c041001 lui $4, 4097 [prompt] ; 35: la $a0, prompt 0x0000000c syscall ; 36: syscall 0x34020005 ori $2, $0, 5 ; 38: li $v0, 5 0x0000000c syscall ; 39: syscall 0x1840000d blez $2 52 [end-0x00400034] ; 41: blez $v0, end 0x34080000 ori $8, $0, 0 ; 42: li $t0, 0 0x01024020 add $8, $8, $2 ; 44: add $t0, $t0, $v0 0x2042ffff addi $2, $2, -1 ; 45: addi $v0, $v0, -1 0x14403ffe bne $2, $0, -8 [loop-0x00400044]; 46: bnez $v0, loop 0x34020004 ori $2, $0, 4 ; 47: li $v0, 4 0x3c011001 lui $1, 4097 [result] ; 48: la $a0, result 0x34240022 ori $4, $1, 34 [result] 0x0000000c syscall ; 49: syscall
\n Please Input a value for N = The sum of the integers from 1 to N is **** Adios Amigo Have a good day ****
0x2020200a 0x76206120 0x20200020 0x20656874 0x2031206d a e l P e s 0x 61656c50 0x49206573 0x7475706e 0x65756c61 0x726f6620 0x3d204e20 0x65685420 0x6d757320 0x20666f20 0x65746e69 0x73726567 0x6f726620 0x4e206f74 0x20736920 0x20200a00
This is an example of an addressing structure called Little Indian where the right most byte in a word has the smaller address.
001101ssssstttttiiiiiiiiiiiiiiii
00110100000000100000000000001010
0x 3 4 0 2 0 0 0 A
000000ssssstttttddddd00000100000
00000001000000100100000000100000
0x 0 1 0 2 4 0 2 0
Lesson #8
Exercise 4.1
Translate the following assembly language instructions to their corresponding machine language codes as they would be represented in hexadecimal. (Hint Refer to Appendix C and Appendix D.) loop: addu $a0, $0, $t0 ori $v0, $0, 4 syscall addi $t0, $t0, -1 bnez $t0, loop andi $s0, $s7, 0xffc0 or $a0, $t7, $s0 sb $a0, 4($s6) srl $s7, $s7, 4 # # # # # # # # # 0x00082021 0x34020004 0x0000000C 0x2108FFFF 0x1500FFFB 0x32F0FFC0 0x01F02025 0xA2C40004 0x0017B902
In Appendix C we are shown how Store Byte is encoded in binary sb Rt, offset(Rs) # Mem[RF[Rs] + Offset] = RF[Rt]
Op-Code Rs Rt Offset
101000ssssstttttiiiiiiiiiiiiiiii
sb $4, 4($22) sb $a0, 4($s6)
10100010110001000000000000000100
0xA 2
0 4
Translating Assembly Language Shift Instruction to Machine Language In Appendix C we are shown how Shift Right Logical is encoded in binary
srl
Op-Code
Rd, Rs, sa
# Rs = Rt << sa
Rt Rd
sa
00000000000tttttdddddvvvvv000010
srl $23, $23, 4 srl $s7, $s7, 4
00000000000101111011100100000010
0x0 0
0 2
PCSpim Translation
[0x00082021 [0x34020004 [0x0000000c [0x2108ffff [0x1500fffc [0x32f0ffc0 [0x01f02025 [0xa2c40004 [0x0017b902 addu $4, $0, $8 ; 3: addu $a0, $0, $t0 ori $2, $0, 4 ; 4: ori $v0, $0, 4 syscall ; 5: syscall addi $8, $8, -1 ; 6: addi $t0, $t0, -1 bne $8, $0, -16 [main-0x00400030]; 7: bnez $t0, main andi $16, $23, -64 ; 8: andi $s0, $s7, 0xffc0 or $4, $15, $16 ; 9: or $a0, $t7, $s0 sb $4, 4($22) ; 10: sb $a0, 4($s6) srl $23, $23, 4 ; 11: srl $S7, $s7, 4
Exercises 4.2
What is the character string corresponding to the following ASCII codes?
Remember that for simulations running on Intelbased platforms, the characters are stored in reverse order within each word.)
0x2a2a2a2a 0x69644120 0x4120736f 0x6f67696d 0x48202d20 0x20657661
****
i d A A s o ogim H -
eva
In Hexadecimal it is printed out as: 0x04ABF54D Algorithm: t2 = &buffer + 11; mem(t2) = 0; t2 = t2 1; for (t0 = 8; t0 > 0; t0 = t0 -1) {t1 = a0 & 15; t1 = t1 + 0x30; a0 = a0 >> 4; if (t1> 57) t1 = t1+7; mem(t2) = t1; t2 = t2-1} mem(t2) = x; mem(t2-1) = 0; mem(t2-2) = 0x20; print the ASCII string in the buffer
Lesson #9
Pseudo Code for the Algorithm: $a1 = &array; $a0 = 0; loop: $t0= Mem($a1); if ($t0 == 0) go to done $a1 = $a1 + 4; $t3 = $t0 & 1; if ($t0 >= 0 & $t3 == 0) else if ($t0 < 0 & $t3 != 0) go to loop done: syscall(1) << $a0; exit
Op-Code Dest. S1,S2 Comments .data .word -29, -30, 75, 34, -2, 90, -11, 98, 1, 0, 76 .text
10101100 00001100
3.
You are given the following two numbers in twos complement representation. Perform the binary addition and indicate if there is signed overflow ? ______ Explain Why:
10100100 + 11101100
Sign extend the 2-digit hex number 0x90 to a 4-digit hex number. 0x_______
Show how the following PSEUDOCODE expression can be efficiently implemented in MIPS assembly language :$t0 = $s0 / 8 - 2 * $s1 + $s2;
$t0, $s0, 3 $t1, $s1, 1 $t0, $t0, $t1 $t0, $t0, $s2
Performance Evaluation
Time and Space Tradeoff The Figure of Merit (FM) we will use is: Total clock cycles required to execute the code plus total number of memory locations required to store the code. Assume: Multiplication requires 32 clock cycles Division requires 38 clock cycles System Calls Read or Write an integer: assume 200 clock cycles Read or Write a string: assume 20 clock cycles
.data .word .asciiz .asciiz .globl .text li la syscall la li jal move li syscall li la syscall li move syscall li syscall
-4, 5, 8, -1 "\n The sum of the positive values = " "\n The sum of the negative values = " main
main: $v0, 4 # system call code for print_str $a0, msg1 # load address of msg1. into $a0 # print the string $a0, array # Initialize address Parameter $a1, 4 # Initialize length Parameter sum $a0, $v0 $v0, 1 # Call sum
# move value to be printed to $a0 # system call code for print_int # print sum of positive values $v0, 4 # system call code for print_str $a0, msg2 # load address of msg2. into $a0 # print the string $v0, 1 # system call code for print_int $a0, $v1 # move value to be printed to $a0 # print sum of negative values $v0, 10 # terminate program run and # return control to system
An Example Function
sum: loop: blez addi lw addi bltz add b negg: retzz: add b jr $v1, $v1, $t0 loop $ra # Add to the negative sum # Branch to loop # Return $a1, retzz $a1, $a1, -1 $t0, 0($a0) $a0, $a0, 4 $t0, negg $v0, $v0, $t0 loop # If (a1 <= 0) Branch to Return # Decrement loop count # Get a value from the array # Increment array pointer to next word # If value is negative Branch to negg # Add to the positive sum # Branch around the next two instructions li li $v0, 0 $v1, 0
Exercise 5.1
Write a MIPS assembly language program to find the Sum of the first 100 words of data in the memory data segment with the label chico. Store the resulting sum in the next memory location beyond the end of the array chico.
chico: result:
400 main
main: $a0, chico $t0, 0 $t1, 100 $t2, 0($a0) $t0, $t0, $t2 $a0, $a0, 4 $t1, $t1, -1 $t1, loop $t0, 0($a0) $v0, 10 # Load address pointer # Clear sum # Initialize loop count # $t2 = Mem(a0) # $t0 = $t0 + $t2 # Inc. address pointer # Dec. loop count # if ($t1 > 0) branch # Store the result # End of program
loop:
lw add addi addi bgtz sw li syscall
Exam Question #4
The following code segment is stored in memory starting at memory location 0x00067890. What are the two possible values for the contents of the PC after the branch instruction has executed? 0x________ 0x
andi $t3, $t1, 1 bnez $t3, test add $t1, $s1, $s0 test:
# # #
4 10
test:
ble li syscall li syscall
Lesson #10
Exercise 5.2
Write an efficient segment of MIPS assembly language code to transfer a block of 100 words starting at memory location SRC to another area of memory beginning at memory location DEST.
main: # $a1 = &SRC #$a2 = &DEST #$t0 = 100 #$t1= Mem($a1) #Mem($a2) = $t1 #$a1 = $a1+4 #$a2 = $a2+4 # $t0 = $t0 - 1 #Branch if $t0 > 0
loop:
Exercise 5.3
Write a MIPS function which accepts an integer word in register $a0 and returns its absolute value in $a0.
Also show an example code segment that calls the ABS function twice, to test the function.
.text ABS: bgez $a0, return # If ($a0 >= 0) done sub $a0, $0, $a0 # $a0 = 0 - $a0 return: jr $ra #Return ######################################## .globl main .text main: li $a0, -9876 jal ABS li $v0, 1 # Output result syscall li $a0, 9876 jal ABS li $v0, 1 # Output result syscall li $v0,10 # End of program syscall
Lesson #11
Exercise 5.4
Write a function PENO (&X, N, SP, SN) that will find the sum of the positive and negative values in an array X of length N. "X" the address of an array, passed through $a0. "N" is the length of the array, passed through $a1. The procedure should return two values: (1) The sum of all the positive elements in the array, passed back through $v0. (2) The sum of all the negative elements in the array, passed back through $v1.
A Function that takes a Binary Value and prints the equivalent Decimal Representation, Right Justified This function is similar to the PrintHex function Except you Divide by 10 instead of 16 Differences: Negative values must be preceded by a Minus. Need to place Leading space spaces (ASCII 20) into the print buffer.
Exercise 5.5
Write a function SUM(N) to find the sum of the integers from 1 to N, making use the multiplication and shifting operations. The value N will be passed to the procedure in $a0 and the result will be returned in the $v0 register.
Write a MIPS assembly language main program that will call the Sum function five times each time passing a different value to the function for N, and printing the results. The values for N are defined below: .data N: .word 9, 10, 32666, 32777, 654321
.text SUM:
# $v0 = $a0 + 1 # $v0 = $v0 * $a0 # Shift right arithmetic # is the quick way to # divide by 2
jr
$ra
Lesson #12
Exercise 5.6
Write a function FIB(N, &array) to store the First N elements of the Fibonacci sequence into an array in memory. The value N is passed in $a0, and the address of the array is passed in register $a1. The first few numbers of the Fibonacci sequence are: 1, 1, 2, 3, 5, 8, 13, ............
fib:
$t0, 1 $t0, 0($a1) $t0, 4($a1) $a0, $a0, -2 $t0, 0($a1) $t1, 4($a1) $t0, $t0, $t1 $t0, 8($a1) $a1, $a1, 4 $a0, $a0, -1 $a0, loop $ra
loop:
Exercise 5.7
Write a function that receives 3 integer words in registers $a0, $a1, & $a2, and returns them in ordered form with the minimum value in $a0 and the maximum value in $a2.
done:
$a0, $a1, done $t0, $a1 $a1, $a0 $a0, $t0 $ra
Exercise 5.8
Write the complete assembly language program,including data declarations, that corresponds to the following C code fragment. Make use of the fact that multiplication and division by powers of 2 can be performed most efficiently by shifting.
# Y= 56 # K= 20 # K/4 # K/4 + 210 # --- x 16 # t2= Y 16 * (K / 4 + 210) # t1=K # scale K # t1= & Z[k] - 8 # Z[K]= Y-16*(k/4+210)
Lesson #13
Exercise 5.9
Write a function to search through an array X of N words to find the minimum and maximum values. The address of the array will be passed to the function using register $a0, and the number of words in the array will be passed in register $a1. The minimum and maximum values are returned in registers $v0, & $v1.
MaxMin: lw move addi blez loop: addi lw bge move b next: ble move chk: addi bgtz ret: $a1, $a1, -1 $a1, loop $t0, $v1, chk $v1, $t0 $a0, $a0, 4 $t0, 0($a0) $t0, $v0, next $v0, $t0 chk $v0, 0($a0) $v1, $v0 $a1, $a1, -1 $a1, ret
jr
$ra
Exercise 5.10
Write a function to find the sum of the main diagonal elements in a two dimensional N by N array of 32 bit words. The address of the array and the size N are passed to the procedure in registers $a0 and $a1 respectively. The result is returned in $v0. The values in registers $a0 and $a1 should not be modified by this procedure. Calculate the number of clock cycles required to execute your algorithm, assuming N=4
.text mdsum: lw move addi sll addi blez loop: add lw add addi bgtz return: jr
$v0, 0($a0) # v0 = first element $t1, $a0 $t3, $a1, 1 # compute offset $t3, $t3, 2 # multiply by 4 $t0, $a1, -1 # init. loop count $t0, return $t1, $t1, $t3 # calc. next address $t2, 0($t1) # t2=Mem(t1) $v0, $v0, $t2 # add to sum $t0, $t0, -1 # decrement loop count $t0, loop $ra
Exercise 5.11
Write a function to find the determinant of a two by two matrix (array). The address of the array is passed to the function in registers $a0 and the result is returned in $v0. The value in register $a0 should not be modified by this function.
Calculate the number of clock ticks required to execute your algorithm.
determ2
$t0, 0($a0) $t1, 12($a0) $t1, $t0 $v0 $t0, 4($a0) $t1, 8($a0) $t1, $t0 $t0 $v0, $v0, $t0 $ra
Lesson #14
Exercise 5.12
Write a MIPS assembly language function that accepts a binary number in register $a0 and returns a value corresponding to the number of ones in the binary number.
Exercise 5.12(Pseudocode)
$v0 = 0; while ($a0 = !0) { $t0 = $a0 & 1; $a0 = $a0 >> 1; $v0 = $v0 + $t0; } Return
.globl count .text count: li $v0, 0 while: andi $t0, $a0, 1 srl $a0, $a0, 1 add $v0, $v0, $t0 bnez $a0, while jr $ra
Exercise 5.13
Translate the following pseudocode expression to MIPS assembly language code. Include code to insure that there is no array bounds violation when the store word (sw) instruction is executed. Note that the array zap is an array containing 50 words, thus the value in register $a0 must be in the range from 0 to 196. Include code to insure that the value in register $a0 is a word address offset into the array zap. If an array bounds violation is detected or the value in register $a0 is not a word address offset then branch to the label Error.
zap:
Lesson #15
Exercise 5.14
Write a function to search through an array X of N words to find how many of the values are evenly divisible by four. The address of the array will be passed to the function using register $a0, and the number of words in the array will be passed in register $a1. Return the results in register $v0.
Div4: li li b loop: lw addi and bnez addi skip: $t2, 0($a0) $a0, $a0, 4 $t0, $t2, $t3 $t0, skip $v0, $v0, 1 $v0, 0 $t3, 3 skip
addi bgez jr
Address
Co ntrol Lo gi c
Rd
Rt
The Stack is in Memory and Register $sp Points to the Top of Stack
<Body of Function> $v0, 12($sp) $v1, 16($sp) $ra # First Out Parameter D at Mem[Sp+12] # Second Out Parameter E at Mem[Sp+16] # Return to JACK
$sp $a0
Lesson #16
Exercise 6.1
MinMax (&X, N, Min, Max)
Write a function to search through an array 'X' of 'N' words to find the minimum and maximum values. The parameters &X and N are passed to the function on the stack, and the minimum and maximum values are returned on the stack. (Show how MinMax is called)
##### An Example of calling the function ##### .data array .space 400 .text addiu $sp, $sp, -16 la $t0, array sw $t0, 0($sp) li $t0, 100 sw $t0, 4($sp) jal MinMax lw $t0, 8($sp) lw $t1, 12($sp) addiu $sp, $sp, 16
Comments
Lesson #17
Memory Layout
0x00000000 0x00400000
Reserved
Text Segment
0x10000000
Operating System
0xFFFFFFFF
Exercise 6.2
Search(&X, N, V, L) Write a function to sequentially search an array X of N bytes for the relative location L of a value V. The parameters &X, N, and V are passed to the procedure on the stack, and the relative location L (a number ranging from 1 to N) is returned on the stack. If the value V is not found the value -1 is returned for L.
.text search: lw lw lw move addi loop: lbu addiu beq addi bgez li sw b found: sub sw jr $t1, $t1, $ra $t1, $t2 12($sp) $t4, $t3, $t4, $t2, $t2, $t4, $t4, exit 0($t3) # get a character $t3, 1 # increment pointer $t0, found $t2, -1 # decrement loop counter loop -1 12($sp) $t3, $t1, $t0, $t2, $t2, 0($sp) 4($sp) 8($sp) $t1 $t2, -1 # get &X # get N # get V # t2 = N - 1
exit:
Exercise 6.3
Scan(&X, N, U, L, D) Write a function to scan an array 'X' of 'N' bytes counting how many bytes are ASCII codes for: a. upper case letters - U b. lower case letters - L c. decimal digits - D
Return the counts on the stack. The address of the array and the number of bytes N will be passed to the function on the stack.
Write a short main program to test this function.
# Deallocate
lowc: $t1, $t7, check # a $t1, $t8, check # z $t4, $t4, 1 check
lw lw addiu sw sw sw jr
$s6, 0($sp) $s7, 4($sp) $sp, $sp, -8 $t3, 8($sp) $t4, 12($sp) $t5, 16($sp) $ra
Lesson #18
Exercise 6.4
Hypotenuse(A, B, H) This is an exercise in calling nested functions and passing parameters on the stack. Write a function to find the length of the hypotenuse of a right triangle whose sides are of length A and B. Assume that a math library function sqr (V, R) is available, which will compute the square root of any positive value V, and return the square root result R. Write a main program to test this function.
jal
lw addi li syscall li syscall
hypotenuse
$a0, $sp, $v0, $v0, 8($sp) $sp, 12 1 10
# Allocate # Pass Value to sqr # Save ra # Call sqr # Get sqr Result # Restore ra # Deallocate # Return Hypotenuse
Lesson #19
Exercise 6.5
AVA (&X, &Y, &Z, N, status) Write a function to perform an absolute value vector addition. Use the stack to pass parameters. The parameters are: the starting address of three different word arrays (vectors) : X, Y, Z, and an integer value N specifying the size of the vectors. If overflow ever occurs when executing this function, an error status of 1 should be returned and the function aborts any further processing. Otherwise, return the value 0 for status. The function will perform the vector addition: Xi = | Yi | + | Zi | ; with i going from 0 to N - 1. Also write a main program to test this function.
Comments
20 345, 765, -234567, 2345, 999 -38645, 765987, 67, 3215, 444 Overflow Occurred
main:
$sp, $s0, $s0, $s0, $s0, $s0, $s0, $s0, $s0, AVA $s0, $sp, $s0, $v0, $a0,
$v0,
# Allocate
# Deallocate
done:
Label
AVA:
Comments
# Get &X # Get &Y # Get &Z # Get N
loop:
next:
sum:
Lesson #20
Exercise 6.6
Fibonacci (N, E) Write an function to return the Nth element in the Fibonacci sequence. A value N is passed to the function on the stack, and the Nth Fibonacci number E is returned on the stack. If N is greater than 46 overflow will occur, so return a value of 0 if N is greater than 46. Also show an example of calling this function to return the 10th element in the sequence. The first few numbers in the Fibonacci sequence are: 0, 1, 1, 2, 3, 5 . . . .
loop:
add move move addi bgtz done: sw jr error: sw jr $0, 4($sp) $ra $t3, 4($sp) $ra
Exercise 6.7
BubSort (&X, N) Write a function to sort an array X of N words into ascending order using the bubble sort algorithm. The address of the array and the value N will be passed to the function on the stack. Show how the sort function is called. Example Assembly Language Code to Call Sort(&Z, 1000) addi $sp, $sp, -8 la $t0, z sw $t0, 0($sp) li $t0, 1000 sw $t0, 4($sp) jal sort addi $sp, $sp, 8
Comments
Exercise 6.8
RipSort (&X, N) Write a function to sort an array X of N words into ascending order using the ripple sort algorithm. The address of the array and the value N will be passed to the function on the stack.
Comments
lw addi move
loop2: move lw addi ble sw sw check: addi bgtz next: addi bgtz jr
Exercise 6.9
Roots(a, b, c, Status, R1, R2) This is an exercise in nested function calls and passing parameters on the stack. Write a procedure to calculate the roots of any quadratic equation of the form y = a*x2 + b*x + c where the integer values a, b, and c are passed to the function on the stack. Status should indicate the nature of the results returned as indicated below: 0 : 2 real roots R1 & R2 1 : 1 real root in R1= -a/b 2 : 2 complex roots of the form (R1 + i R2) 3 : no roots computed (error) Assume that a math library function sqr is available, that will compute the square root of a positive argument.
Lesson #21
Reentrant Functions
It is important that all shared operating system functions and library functions running on a multi-tasking computer system be reentrant. (Examples: text-editor or compiler)
Exercise 7.1
Reverse
Write a reentrant function that will read in a string of characters (60 Characters Maximum) and will print out string in reverse.
For Example the input string July is Hot will be printed out as toH si yluJ.
See Appendix A
Read String has the same semantics as the Unix library routine fgets. It reads up to n 1 characters into a buffer and terminates the string with a null byte. If fewer than n 1 characters are on the current line, Read String reads up to and including the newline and again null-terminates the string
J u l y
Ho t
# Allocate space for 2 buffers 64 bytes each # Initialize pointer to input buffer
# Read a string # Initialize pointer to end out output buffer # null terminator
# Allocate space
rev:
$sp, $sp, 128 $a0, $sp $a1 , 61 $v0, 8 $t4, 10 $a1, $sp, 127 $0, 0($a1) $t1, 0($a0) $a0, $a0, 1 $t1, $t4, print $a1, $a1, 1 $t1, 0($a1) loop $a0, $a1 $v0, 4 $sp, $sp, 128 $ra
loop:
Lesson #22
Exercise 7.2
Palindrome (b) Write a reentrant function that will determine if a string is a palindrome. The function should read in a string (14 characters max) placing them in a buffer on the stack. This procedure should call a Search function to determine the exact number of actual alphabetic characters in the string. A Boolean value of true or false (1 or 0) will be returned on the stack to indicate if the string is a palindrome.
sp = sp + 16 Mem(sp) = t2 return
$sp, $sp, -20 $t7, 0($sp) $t0, 16 $t0, 4($sp) $t0, 10 $t0, 8($sp) $ra, 16($sp) srch $ra, 16($sp) $t8, 12($sp) $sp, $sp, 20
#<<<<<<<<<<<<<<<
# Call Search(&X, N, V, L)
#<<<<<<<<<<<<<<<<
Lesson #23
Exercise 7.6
Write an efficient MIPS assembly language function Scan(&X, Num) that will scan through a string of characters with the objective of locating where all the lower case vowels appear in the string, as well as counting how many total lower case vowels appeared in a string. Vowels are the letters a, e, i, o, u. The address of the string "X" is passed to the function on the stack, and the number of vowels found NUM is returned on the stack. A null character terminates the string. Within this function, you must include code to call any students PrintDecimal function to print, right justified, the relative position within the string where each vowel was found. Notice this will be a nested function call. Here is an example string: The quick brown fox. For the above example string the output of your program would be A Vowel was Found at Relative Position : A Vowel was Found at Relative Position : A Vowel was Found at Relative Position : A Vowel was Found at Relative Position : A Vowel was Found at Relative Position : 3 6 7 13 18
$sp, $sp, -16 $t8, 0($sp) $t5, 4($sp) $t6, 8($sp) $ra, 12($sp) PrintDecimal $t8, 0($sp) $t5, 4($sp) $t6, 8($sp) $ra, 12($sp) $sp, $sp, 16 again
$t6, 4($sp) $ra
# <<<<<<<<<<<<<<<<
msg:
Lesson #24
$v0 = Mem($sp); For (a0 = $v0 1; $a0 > 0 ; $a0 = $a0 1) Label Op-Code Dest. S1, S2 Comments $v0 = $v0 * $a0; Fac: Mem($sp+4) = $v0; lw $v0, 0($sp) Return
addi $a0, $v0, -1
$a0, return $v0, $a0 $v0 $a0, $a0. -1 loopf $v0, 4($sp) $ra loopf: blez mult mflo addi b return: sw jr
#<<<<<
facret:
addiu sw jr Prob: sw jr $0, 4($sp) $ra $sp, $sp, 16 #<<<< $v0, 4($sp) $ra
# Get N
# Return N!
# Recursive Call # $a0 = Fib (N-2) # <<<< De-allocate Space # Fib (N-1) + Fib (N-2)
Exercise 7.5
Write a recursive function to find the determinant of a N x N matrix (array). The address of the array M and the size N are passed to the function on the stack, and the result R is returned on the stack: det (&M, N, R)
5 1 4 2 6
8 6 7 1 8
0 1 8 1 4
2 9 1 2 1
3 5 2 0 1
$t9 = Mem(sp+4); # get size N if ( $t9 < 2) { Mem(sp+8) = 0; return} If ( $t9 == 2) Mem(sp+8) = Det2 else {t5 = t9 -1 # Size of cofac matrix t4 = (t5 * t5) *4 # Dynamic storage alloc. sp = sp - t4 - 12 # Allocate space for cofac matrix + arg Mem(sp + 4) = t5 # Pass size (N-1) Mem(sp) = sp + 16 # Pass addr. cofac matrix t3=0 # accumulator for (t6 = 0; t6 < t9; t6 = t6+1) { Put col t6 cofac matrix on stack push t3,t4,t5,t6,t9 registers on stack call det(&m, n, r) restore t3,t4,t5,t6,t9 registers from the stack t5=Mem(sp+ 8) #result If (t6 && 1== 0) t3= t3 + t5 else t3= t3 - t5 } sp = sp + t4 + 12 #clean up stack return
Lesson #25
Exercise 8.1
Write your most efficient MIPS assembly language code translation for the following function and main line calling program. Note, all communication with the function must use a stack frame. Make use of the fact that multiplication and division by powers of 2 can be performed most efficiently by shifting.
int main() {int J, K, L , M ; cin >> J, K, L; chico ( &J, K, L); M = J - ( K + L); cout << M; return 0
}
$t0, 0($sp) $t1, 4($sp) $t2, 8($sp) $t1, $t1, 2 $t3, $t2, 1 $t2, $t2, 3 $t2, $t2, $t3 $t1, $t1, $t2 $t3, 0($t0) $t3, $t3, 3 $t3, $t1, $t3 $t3, 0($t0) $ra
# Z * 10 # $t1 gets partial result # $t3 gets value of X #X *8 # $t3 gets result # J is assigned the result
Comments
# Put value for L :$s2 # Allocate for 3 Par. <<<<<<<<<2 # Calc. address of J < # Put address of J on stack < # Put value of K on stack < # Put value of L on stack < < # Deallocate <<<<<<<<<<<<<<<2
lw add sub
li syscall
addiu <<<<<<<<<<1
$v0, 1
# Print M $sp, $sp, 16 # De-allocate 4 Local Main Var
li syscall
$v0,
10
Lesson #26
Exercise 8.2
MUL32 ( m, n, p, f) Write a function MUL32( m, n, p, f) that will find the 32-bit product p of two arguments m and n. If the twos complement representation of the product cannot be represented with 32 bits, then the error flag f should be set to 1 otherwise the error flag is set to 0. Pass all arguments on the stack.
# Get correct sign for prod # $t6 = 32 bit product # compare signs
# $t8 = Upper 32-bits of prod
pos:
Exercise 8.3
Adduovf ( x, y, s) Write a function Adduovf( x, y, s) that will find the 32-bit sum s of two unsigned arguments x and y. An exception should be generated if the unsigned representation of the sum results in overflow. Perform all communication on the stack. Hint:
A carry out at the most Significant Digit (MSD) is Overflow for unsigned numbers.
Exercise 8.4
Write a function Add64 that will perform a 64-bit addition: x = y + z, where the values for x, y, and z are stored as two 32-bit words each: Add64(x1: $t1, x0: $t0, y1: $t3, y0: $t2, z1: $t5, z0: $t4) All six parameters are passed on the stack. If the 64-bit sum results in overflow an exception should be generated. After writing your code, calculate the performance indexes: Space:_________________(Words of code) Time: _________________(Maximum number of clock cycles to execute)
Exercise 8.5
When the MIPS mult instruction is executed, a 64-bit product is produced. Many programs doing numerical calculations are designed to process only 32-bit results. For applications written to perform 32-bit precision arithmetic, it is extremely important to detect when the product of two numbers can not be represented with 32 bits, so that some alternative procedures may be invoked.
Write a reentrant library function anyone could use, called MUL32(m, n, p). All function parameters will be passed on the stack. This function should provide the following features: 1. If the product of the two input arguments m and n cannot be represented with 32 bits (assuming the twos complement number system), then an exception should be generated. 2. This function should also provide the following optimization features: (a) Check if m or n is zero, and return zero without taking 32 clock cycles to execute the mult instruction. (b) Check if m or n is plus one (1) or minus one (-1), and return the correct result without taking 32 clock cycles to execute the mult instruction. (c) Check if m or n is plus two (2) or minus two (-2), and return the correct result without taking 32 clock cycles to execute the mult instruction. If the product cannot be represented with 32-bits, then an exception should be generated.
Lesson #27
Address =
Rd
Data In
Rt
Write Back
Exercise 9.1
Taking into consideration delayed branches and delayed loads, write a MIPS function to search through an array X of N words to find how many of the values are evenly divisible by four. The address of the array will be passed to the function using register $a0, and the number of words in the array will be passed in register $a1. Return the results in register $v0.
Div4: li li b loop: lw addi and bnez addi skip: $t2, 0($a0) $a0, $a0, 4 $t0, $t2, $t3 $t0, skip $v0, $v0, 1 $v0, 0 $t3, 3 skip
Div4: li b li loop: nop and bnez addi addi skip: addi bgez lw jr nop $a1, $a1, -1 $a1, loop $t2, 0($a0) $ra $t0, $t2, $t3 $t0, skip $a0, $a0, 4 $v0, $v0, 1 $v0, 0 skip $t3, 3
addi bgez jr
Exercise 9.2
Taking into consideration delayed branches and delayed loads,
Write a MIPS function to sort an array Z of N words into ascending order using the bubble sort algorithm. The address of the array and the value N will be passed to the function on the stack. Show how the sort function is called.
Original Code to Call Sort(&Z, 1000) Modified Code to Call Sort(&Z, 1000) addi $sp, $sp, -8 addi $sp, $sp, -8 la $t0, z la $t0, z sw $t0, 0($sp) sw $t0, 0($sp) li $t0, 1000 li $t0, 1000 sw $t0, 4($sp) jal sort jal sort sw $t0, 4($sp) addi $sp, $sp, 8 addi $sp, $sp, 8
&Z
addi bgtz
bnez jr
Lesson #28
Exercise 9.3
Taking into consideration delayed branches and delayed loads, Write a function Adduovf( x, y, s) that will find the 32-bit sum s of two unsigned arguments x and y. An exception should be generated if the unsigned representation of the sum results in overflow.
diff:
bgez jr
Exercise 9.4
Taking into consideration delayed branches and delayed loads, write a MIPS, function to return the Nth element in the Fibonacci sequence. The value N is passed to the function on the stack, and the Nth Fibonacci number E is returned on the stack. If N is greater than 46 overflow will occur, so return a value of 0 if N is greater than 46. Also show an example of calling this function to return the 10th element in the sequence. The first few numbers in the Fibonacci sequence are: 0, 1, 1, 2, 3, 5 . . . .
Embedded Processors
Exercise 10.1
Random(&X, N) Write a function that will generate and store N random numbers into an array X. Use the value in register $ra as the initial seed value. A possible algorithm for generating random numbers appears below: $a0 = Mem($sp) $a1 = Mem($sp+4) $t0 = $ra for ( ; a1> 0; a1 = a1 1) {$t0 = $t0 * 2743 + 5923 Mem($a0) = t0 $a0 = $a0 + 4 } return
main:
#call Sort(&x, N)
li $v0, 10 syscall