---------------------------------------------------------------------------- CDA3101 - Spring 2016 - Exam #2 Review ---------------------------------------------------------------------------- TOPICS WE HAVE COVERED THAT CAN BE ON EXAM-2: (Study these in Book and Web Notes) 3.Computer Arithmetic 3.4. Floating Point Arithmetic 3.5. Floating Point in MIPS 4. Processors 4.1. The Central Processor - Control and Dataflow 4.2. Datapath Design and Implementation 4.3. Single-Cycle and Multicycle Datapaths 4.4. Controller Finite State Machines 4.5. Microprogrammed Control 5. Pipelining 5.1. Overview of Microprogramming and Pipelining 5.2. Pipeline Datapath Design and Implementation 5.3. Pipeline Control and Hazards TYPES OF QUESTIONS: - Short Answer (1-2 sentences - no dissertations, please) - Computation (e.g., convert a binary number to its decimal value, do signed or unsigned addition, subtraction, mul- tiplication, or division) - Programming (maybe one or two very simple MIPS code fragments, on pointers and addressing only)) - Comparison For example, compare software and hardware features of CISC vs. RISC... EXAMPLE QUESTIONS: (answers in blue typeface) * Write a MIPS program to add the first eight powers of 7 (e.g., 7 + 7^2 + 7^3 + ... + 7^8) Writing MIPS programs with decision structures in them is easy if you first convert the program to HLL, then express it using the dreaded go-to statement. For example, consider the following pseudocode (not exactly C language): int sumsevens(int n): { int sum, i, n ; sum = 0 ; for i = 0 to n-1 do: sum := sum + 7^i ; return(sum) } main(): { return(sumsevens(8)) } All you need to do at this point is to rewrite the loop and get rid of the function call: int main(): { int sum, i i = 8 ; sum = 0 ; L: sum = sum + 7^i i = i - 1 ; if i >= 0 goto L ; X: return(sum) } Thus, the MIPS program will be comprised of the following rough parts (expressed in p-code): put $0 in $s0 # sum = 0 [in $s0] put 8 in $t0 # i = 8 [in $t0] put 1 in $s1 # constant[in $s1] L: put $t0 in $a0 # sum = sum + 7^i jal to procedure pow7 # $v0 gets 7^i add $v0 to $s0 # sum = sum + 7^i sub 1 from $t0 # i = i - 1 slt $t2, $t0, $0 # if 0 < i bne $t2, $s1, L # goto L beq $t0, $0 , L # if i = 0 goto L X: put $s0 in $v0 # return(sum) and the procedure pow7 is given by the following p-code: pow7($a0): { pow = 1 ; for j = 1 to $a0 do: pow = pow * 7 } Since you already know how to transform a loop and how to use a MIPS multiplication instruction, you can fill in the remainder from your knowledge of MIPS instructions and the material we discussed in class. * Write a MIPS program to compute the first 20 Fibonacci numbers Again, the approach is to write the Fibonacci generator in HLL, then translate it to HLL with goto and if as the decision-related structures. For example: Given F(1) = 1 and F(2) = 2, F(i) = F(i-1) + F(i-2) for i >2. the core procedure is: Fib(i) { int i, Fib ; if i < 1 then { printf("Error"); exit } if i = 1 then return(1) ; if i = 2 then return(2) ; if i > 2 then return(Fib(i-1) + Fib(i-2)) } You can reduce the above if statements to instances of slt followed by bne or beq instruction (for testing i < 1 and i > 2), or simple beq for testing i = 1 and i = 2. The method for translating a recursive procedure to MIPS is given in Section 2.3.8.5 of the Web notes. Once you have these building blocks, then you can construct the MIPS code as follows: - initialize Fib, get i from $a0 - test for i < 1 using slt and beq, with jal to printf (you do not have to specify the "error" message goto Exit if the test succeeds - test for i = 1 using beq with 1 in a register put 1 in $v0 if the test succeeds - test for i = 2 using beq with 2 in a register put 2 in $v0 if the test succeeds - test for i > 2 using slt and beq if the test succeeds, then you need to: a) push $a0 and the current value of i on the stack b) jump-and-link to procedure Fib as in Example 11 of Section 2.3.8.5 of the Web notes When the recursion has fully wound up the stack, then you can unwind the stack by popping off the items specific to that given invocation of the procedure Fib (e.g., the args and the value of i), then computing Fib. This technique is shown in Example 11 (which used a factorial instead of a Fibonacci number). * Write a MIPS program to sum the even integers from -102 to +108. This is an easy problem, if you realize that for any integer i, the product 2*i will be an even integer. Thus, you can loop from -51 to +54, as shown in the following pseudocode: sumints() { int i, sum i = -51 ; L: sum = sum + 2*i ; i = i -1 ; if ( i < 55 ) then goto L ; X: return(sum) } At this point, we can write the MIPS program using the methods shown in the previous examples and in class. * How are MIPS programs produced, and what type of code is involved? Answer: MIPS programs are produced in assembly language by (a) a programmer using an editor, or (b) by a compiler translating high-level programming language (HLL) to assembly. An assembler translates the assembly language to object code, which is combined with libraries by a linker, to produce machine code. A loader or runtime module puts the machine code into memory and saves the start address A so execution can begin by loading A into the PC. * What is the difference between assembly and object code? Answer: Assembly code is written with pseudo-names for the registers, text labels, and has the result register first in the list of operands. The assembler resolves dependencies, codes the register addresses in terms of numbers, and translates the labels to addresses. If libraries are called, the dependencies are resolved by the linker. * What is a pointer, and what is it used for? Answer: A pointer is an address that it is used to reference data directly in memory. * How is pointer arithmetic used in programming practice? Answer: By incrementing or decrementing pointers, you can efficiently access large amounts of data without actually having to handle the parts of memory that store the data. For example, instead of passing large arrays in the argument list of a function (call-by-value), we pass the pointers to the arrays (call-by-reference). * How do load/store operations in MIPS relate to pointer arithmetic? Answer: If x is a variable and p is a pointer, and you have the C-like statement "p = &x", this is like fetching the address of a memory element in MIPS. If you have "x = *p", that is like a load operation in MIPS, because it says "the variable x contains the data referenced by pointer (address) p." Conversely, if you have "*p = x", that is like a store operation, since it means "put the contents of x into memory at address p." * How is the MIPS ALU and coprocessor used for floating point arithmetic operations? Answer: The MIPS ALU has some floating point instructions (e.g., add.s, mul.d) in its ISA, but these are executed on a coprocessor, which has floating-point hardware. Execution of a floating point instruction involves (a) shipping the data from the MIPS processor to the coprocoessor, (b) executing the FP instruction on the coprocessor, and (c) returning the result to the MIPS processor. * How does Booth's algorithm for multiplication work, and why is it used? Answer: Booth's algorithm is designed for multiplication of signed binary numbers. It uses a two-symbol classifier to determine if the multiplier should be shifted, added, or subtracted from the accumulated product. This algorithm works only for two's complement arithmetic, since the leading 1 (or zero) in the partial multiplier induces the correspondingly signed partial product, which is then added to the accumulated product. The use of the current and next bits in the multiplier help determine what the sign of the partial product should be. * What is the IEEE 754 standard, and how is it used? Answer: The IEEE 754 standard describes operand formats for single- and double-precision floating-point arithmetic. The standard is used to make FP operations on computers more consistent, reliable, and accurate by having everyone adhere to the standard in the design of FP libraries and programs that use FP operations. * What are denorms in IEEE 754, and why are they used? Answer: Denorms are a special value in IEEE 754 FP standard that allows one to express operands as small as 2-150. These are necessary because the standard IEEE 754 single precision notation only allows values as small as 2-126 to be expressed. Here, we assume that absolute values are discussed. Thus, denorms are a way of extending the precision of IEEE 754 numbers without extending the format to double precision. Denorms can also be used for double precision numbers. * Convert the unsigned number 101101 (base two) to decimal form. Working upward (leftward) from the LSB, we have: 1 x 20 + 0 x 21 + 1 x 22 + 1 x 23 + 0 x 24 + 1 x 25 = 1 + 0 + 4 + 8 + 0 + 32 = 4510 * Convert the twos complement number 101110 to decimal form. There are six significant digits in the representation. Therefore, the representation 101110 in twos complement means: -1 x 25 + 0 x 24 + 1 x 23 + 1 x 22 + 1 x 21 + 0 x 20 = -32 + 0 + 8 + 4 + 2 + 0 = -32 + 14 = -1810 * Write a MIPS program to perform the following operation in floating point (IEEE 754): y = 2*x + z^3, where x and z are single-precision, and y is double-precision Answer: Here is how the program is structured: Step 1: Send x and z to the coprocessor Step 2: On the coprocessor, multiply temp = z * z, and check for overflow (using the hi and lo registers) Step 3: On the coprocessor, multiply temp = temp * z, and check for overflow (using the hi and lo registers) Step 4: On the coprocessor, multiply temp2 = 2 * x, and check for overflow (using the hi and lo registers) Step 5: On the coprocessor, set y = temp2 + temp1, and check for overflow (using the hi and lo registers) Step 6: Get y from the coprocessor, and store it in the MIPS processor's hi and lo registers -EOF-