231 Fall 2008 -- Exam 2 (with answers) Name: _________________ No calculators. 1. Convert these numbers between signed decimal and 16-bit two's complement representation in hexadecimal. (4 pts. each) signed decimal two's complement (hex) a. +147 __0x0093__ b. __+327__ 0x0147 c. -147 __0xff6d__ d. ___-19__ 0xffed 2. Give the most negative 4-bit two's complement number in two formats: (2 pts. each) a. hexadecimal representation (two's complement): __0x8__ b. decimal representation: __-8__ 3. Give the most positive 4-bit two's complement number in two formats: (2 pts. each) a. hexadecimal representation (two's complement): __0x7__ b. decimal representation: __+7__ 4. Give the names of the following condition code. (4 pts.) N: __negative__ V: __overflow__ Z: __zero______ C: __carry_____ 5. Show the hexadecimal results of binary addition and subtraction of signed 16-bit two's complement numbers. Identify any signed overflows. (8 pts. each) a. 0x6543 b. 0x6543 + 0x89ab - 0x89ab -------- -------- 0xeeee 0xdb98 no overflow overflow 6. Show the hexadecimal results of logic operations on 16-bit binary numbers. (4 pts. each) a. 0x6543 b. 0x6543 or 0x5555 and 0x5555 --------- ---------- 0x7557 0x4541 c. 0x89ab shift d. 0x89ab shift right left by 2 arithmetic by 2 ------------ ------------------ 0x26ac 0xe26a 7. Give a short sequence of SPARC shift and add (or subtract) instructions to multiply the value in register %o0 by 10 decimal and place the result in register %o1. (Do not call .mul or use a multiply instruction.) (4 pts.) --- POSSIBLE ANSWER --- sll %o0, 3, %o1 ! 8x add %o1, %o0, %o1 ! 9x add %o1, %o0, %o1 ! 10x --- ALTERNATE ANSWER --- sll %o0, 3, %o1 ! 8x sll %o0, 1, %o2 ! 2x add %o1, %o2, %o1 ! 10x 8. Show the big-endian and little-endian byte ordering of the following data values. Start the byte numbering of s[] at address 100. (8 pts.) char s[4] = {'a', 'b', 'c', '\0'}; short int u = 0x123; /* short int is 16-bit half word */ short int v = 0x4567; byte address: 100 101 102 103 104 105 106 107 big-endian ordering: _a_ _b_ _c_ _0_ _01_ _23_ _45_ _67_ little-endian ordering: _a_ _b_ _c_ _0_ _23_ _01_ _67_ _45_ |<-------t[]------->| |<--u-->| |<--v-->| character array short int short int four bytes two bytes two bytes 9. Consider a program that requires a number with four hex digits as input. Give a sequence of SPARC instructions to convert four 8-bit ASCII characters held in %o0 into the corresponding 16-bit value in %o1. For example, if %o0 holds '1','a','2','0' = 0x31613230, then %o1 = 0x00001a20. ASCII codes for '0'-'9' are 0x30-0x39 and for 'a'-'f' are 0x61-0x66. You may assume that 'a'-'f' digits are always in lowercase and that all four bytes have already been range checked. It may help to write the problem as pseudo-code on the left-hand-side of the paper. (16 pts.) --- note: turned out to be too difficult for an in-class exam --- --- would have been simpler for four octal digits as input --- desired outcome for example +------------------------+ | 3 1 6 1 3 2 3 0 | +------------------------+ ---- ---- ---- ---- \ \ \ | '1' = 0x31 => hex 1 \ \___ \ | 'a' = 0x61 => hex a \______ \ \ | '2' = 0x32 => hex 2 \ \ \ | '0' = 0x30 => hex 0 +------------------------+ | 0 0 0 0 1 a 2 0 | '0'-'9' => subtract 0x30 +------------------------+ 'z'-'f' => subtract 0x57 --- POSSIBLE ANSWER --- pseudo code // work left-to-right result = 0 repeat 4 times shift result to left by 4 shift input to right (by 24, 16, 8, 0) mask to get 8 bits subtract 0x30 or 0x57 as appropriate or value into result C code result = 0; shiftcnt = 24; for( i = 0; i < 4; i++ ){ result = result << 4; digit = (input >> shiftcnt) & 0xff; digit = digit - 0x30; if(digit > 9) digit = digit - 0x27; result = result | digit; shiftcnt = shiftcnt - 8; } assembly define(input_r,o0) define(result_r,o1) define(digit_r,l0) define(loopcnt_r,l1) define(shiftcnt_r,l2) clr %result_r mov 24,%shiftcnt_r clr %loopcnt_r loop: cmp %loopcnt_r, 4 bge done nop sll %result_r, 4, %result_r srl %input_r, %shiftcnt_r, %digit_r and %digit_r, 0xff, %digit_r sub %digit_r, 0x30, %digit_r cmp %digit_r, 9 ble digit_in_range nop sub %digit_r, 0x27, %digit_r digit_in_range: or %result_r, %digit_r, %result_r sub %shiftcnt_r, 8, %shiftcnt_r inc %loopcnt_r ba loop nop done: 10. Show the HARDWARE STEPS required in multiplication of two unsigned 4-bit binary numbers, 1010 times 1101. (1010 is the multiplicand and 1101 is the multiplier.) The details of mulscc are not required, but you should show the C (carry) and 4-bit ACC, MQ, and MDR registers, and be sure to place the multiplicand and multiplier in the correct registers. (12 pts.) (Note: no credit will be given for mere paper and pencil multiplication.) --- ANSWER --- 1010 4-bit multiplicand x 1101 4-bit multiplier ---------------------------------------------- initially: C ACC MQ 0 0000 1101 MDR 1010 ---------------------------------------------- step 1: 0 0000 1101 + 1010 ^ add based on lsb=1 ------ 0 1010 1101 >> shift right 0 0101 0110 ---------------------------------------------- step 2: 0 0101 0110 + 0000 ^ no add based on lsb=0 ------ 0 0101 0110 >> shift right 0 0010 1011 ---------------------------------------------- step 3: 0 0010 1011 + 1010 ^ add based on lsb=1 ------ 0 1100 1011 >> shift right 0 0110 0101 ---------------------------------------------- step 4: 0 0110 0101 + 1010 ^ add based on lsb=0 ------ 1 0000 0101 >> shift right 0 1000 0010 ---------------------------------------------- check: 1010 10 x 1101 x 13 -------- ---- 10000010 = 128 + 2 = 130 ---------------------------------------------- Extra Credit Show the HARDWARE STEPS required in restoring division of an unsigned 8-bit binary dividend, 00101010, by a 4-bit unsigned binary divisor, 0111. Use the C (carry) and 4-bit ACC, MQ, and MDR registers, and be sure to place the dividend and divisor in the correct registers. (10 pts.) --- ANSWER --- 00101010 8-bit dividend / 0111 4-bit divisor ------------------------------------------------------------- initially: C ACC MQ 0 0010 1010 MDR 0111 (step 0: ( MDR != 0 ) and ( MDR > ACC ) so no exceptions) ------------------------------------------------------------- step 1: 0 0010 1010 << shift left 0 0101 010. - 0111 subtract ------ 1 1110 0100 ^ set to 1 since subtract unsuccessful + 0111 restoring add ------ 0 0101 0100 ------------------------------------------------------------- step 2: 0 0101 0100 << shift left 0 1010 100. - 0111 subtract ------ 0 0011 1001 ^ set to 1 since subtract successful ------------------------------------------------------------- step 3: 0 0011 1001 << shift left 0 0111 001. - 0111 subtract ------ 0 0000 0011 ^ set to 1 since subtract successful ------------------------------------------------------------- step 4: 0 0000 0011 << shift left 0 0000 011. - 0111 subtract ------ 1 1001 0110 ^ set to 0 since subtract unsuccessful + 0111 restoring add ------ 0 0000 0110 ------------------------------------------------------------- remainder | quotient is in ACC | is in MQ 0000 | 0110 ------------------------------------------------------------- check: 00101010 42 / 0111 / 7 -------- ---- quotient 0110 = 6 r 0 remainder 0000 -------------------------------------------------------------