CSE3101 Fall 2004 Exam #2, open book, open notes. Name __________________ 3 points each. ANSWERS How many numeric FPU registers are there? 8 How many bits in one register? 80 How many rounding modes are there? 4 FLD and FILD convert to what type? tbyte (long double) What instruction changes the rounding mode? FLDCW (to set bits 10-11) What instruction enables division by zero errors? FLDCW (to clear bit 2 or ZM) Which type may be denormal without underflow? tbype What are the smallest and largest types accepted by FLD? real4, tbyte What are the smallest and largest types accepted by FILD? word, qword What are the smallest and largest types accepted by FIADD? word, dword Circle True or False (3 pts each). ANSWERS T Reading an unitialized FPU register may cause a run time exception. T FLD executed 9 times in a row will cause a stack overflow exception. T A REAL8 is accurate to about 14 decimal digits of precision. F FIST always rounds toward zero. F FILD expects its operand to be unsigned. Write code to jump to label L1 if ST(0) is 0 (10 pts). ; ANSWER (there are many) ftst fnstsw ax sahf jz L1 ; or this on a .686 fldz fucomip je L1 Suppose a and b are REAL8 and j is type DWORD. Write assembly code equivalent to the following C statements without calling any C functions or using any other memory locations. a = abs(j + 1.0); (10 pts). ; ANSWER fld1 fiadd j fabs fstp a a = sqrt(a*a + b*b); (10 pts). ; ANSWER fld a fmul a fld b fmul b fadd fsqrt fstp a a = pow(a, b); (assume a > 0, 15 pts). ; ANSWER a^b = 2^(b*lg(a)) = 2^(int(b*lg(a))) * 2^(frac(b*lg(a))) fld b fld a fyl2x ; st = b*lg(a) fld st ; 2 copies frndint fxch fsub st, st(1) ; integer part of b*lg(a) in st(1), fractional part in st(0) f2xm1 ; st = 2^(frac(b*lg(a))) - 1 fld1 fadd fscale ; st = a^b fstp a ; This works but leaves garbage in st that ought to be popped. ; To remove it you could replace the last instruction with: fxch fucomp ; pop fstp a ; or pop with FFREE ST, FINCSTP or the undocmented FFREEP ST Write code to print ST(0) by calling _printf (10 pts). ; ANSWER extern _printf: near .data fmt db "%f", 10, 0 .code add esp, -8 fst real8 ptr [esp] push offset fmt call _printf add esp, 12