CMSI 284 - Spring 2009 - Final Exam Answers PROBLEM 1 --------- Convert the following codepoints to UTF-8 (Express your answer in hex): 00032b12 ____________________________ 0000fade ____________________________ 00007fff ____________________________ Answer: 00032b12 ===> f0 b2 ac 92 0000fade ===> ef ab 9e 00007fff ===> e7 bf bf PROBLEM 2 --------- Give the single precision IEEE-754 encoding of -1026.625 and explain your answer. Answer: -1026.625 = -(10000000010.101)[base 2] x 2^0 = -(1.0000000010101)[base 2] x 2^10 = -(1.0000000010101)[base 2] x 2^(137-127) sign exponent fraction ---- -------- ----------------------- 1 10001001 00000000101010000000000 C4806400 PROBLEM 3 --------- Give x86 logic operations to perform the following operations on the esi register (assuming that it contains an unsigned number). Complement every odd-numbered bit ___________________________________ Replace it with its value mod 64 ____________________________________ Replace it with the largest multiple of 64 less than or equal to itself __________________________________ Answer: xor esi, 0aaaaaaaah and esi, 0000003fh and esi, 0ffffffc0h PROBLEM 4 --------- Write a C function that reverses an array of integers, that is implemented by using pointers, not array indexes, to manipulate the array. I shouldn't have to tell you, but I will anyway, that the two arguments to the function have type int* and int. The second one is the array length, of course. Answer: void reverse(int* a, int len) { int* b = a + (len - 1); while (a < b) { int t = *a; *a++ = *b; *b-- = t; } } PROBLEM 5 --------- Write, in assembly language, a function that is intended to be called from C, that takes in an array of ints (and its length) and returns the maximum value in the array. Do not use any conditional jumps other than one to determine when you are "done" iterating through the array. Implement the function the easy way, with cmovg. Answer: _arraymax: mov edx, [esp+4] ; starting address of array mov ecx, [esp+8] ; length mov eax, 80000000h ; minimum integer value test ecx, ecx js done ; bail if negative length check: cmp [edx+ecx*4], eax cmovg eax, [edx+ecx*4] ; update max dec ecx jnz check done: ret PROBLEM 6 --------- What does this code fragment do? xor eax, ebx xor ebx, eax xor eax, ebx Answer: It swaps the values in eax and ebx. Proof: Let a = the original value in eax and b = the original value in ebx. Then Instruction eax ebx =================== =================== =================== xor eax, ebx a xor b b xor ebx, eax a xor b b xor (a xor b) = a xor eax, ebx a xor b xor a = b a PROBLEM 7 --------- Implement the following in NASM: int spfft(int a, int b, int* c, int d) { if (&b < c) return a / b / *c % d; else return d * *c; } Answer: spfft: mov eax, esp add eax, 8 cmp eax, [esp+12] jnl else_part mov eax, [esp+4] cdq idiv [esp+8] cdq mov ecx, [esp+12] idiv [ecx] cdq idiv [esp+16] mov eax, edx ret else_part: mov eax, [esp+16] mov ecx, [esp+12] imul eax, [ecx] ret PROBLEM 8 --------- Write the following in assembly language (use the C calling convention). It is supposed to compute a*log10(b). Use the fyl2x and fldl2t instructions. double f(double a, double b); Answer: f: fld qword [esp+4] fldl2t fdivp fld qword [esp+12] fyl2x ret PROBLEM 9 --------- Explain in detail how the following computes the minimum of the two signed numbers in eax and ebx. (Hint: give your explanation in two parts — one in which eax starts off less than ebx and the other where it doesn't.) sub eax, ebx cdq and edx, eax add ebx, edx Answer: Let a = the initial value in eax, and b = the initial value in ebx. Case 1: a < b sub eax, ebx puts a-b in eax, which is negative cdq puts FFFFFFFF in edx and edx, eax puts a in edx, because anding with F's change nothing add ebx, edx puts b+(a-b) = a in ebx. And a is the minimum. w00t! Case 2: a >= b sub eax, ebx puts a-b in eax, which is non-negative cdq puts 0 in edx and edx, eax puts 0 in edx, because anding with 0's clear add ebx, edx puts b+0 = b in ebx. And b is the minimum. w00t! PROBLEM 10 ---------- What well-known mathematical function is this? mystery: cdq xor eax, edx sub eax, edx ret Answer: It returns the absolute value of eax. Let a = the initial value in eax, and b = the initial value in ebx. Case 1: a < 0 cdq puts FFFFFFFF in edx xor eax, edx complements eax sub eax, edx subtracts -1, i.e., adds 1 to eax. Complementing then adding 1 is negating, and negating a negative number is exactly taking the absolute value Case 2: a >= 0 cdq puts 0 in edx xor eax, edx leaves eax unchanged sub eax, edx subtracts 0, leaving eax unchanged. That's absolute value for a non-negative number.