; Jade Yu Cheng ; ICS 312 ; Assignment 7 Exercise 2 ; April 24, 2009 ; driver_ex2.c defines a main function. It takes two command-line arguments, ; both of them are floating point numbers. The program defines a function, f, ; which takes as argument a float and returns a float. In the program as it is ; written this function is the f(x) = x2 + 10/x function. The program calls a ; function called compute_derivative. This function takes three arguments. The ; first argument is a "function pointer", that is the address of a function. ; The second argument is a float, which is the point at which the function's ; derivative should be computed (x). The third argument is a float, which is ; the level of precision at which the derivative should be computed (epsilon). ; You can see in the program that the function passed to compute_derivative is ; function f, that the value of x comes from the first command-line argument, ; and that the value of epsilon comes from the second command-line argument. %include "asm_io.inc" %define f dword [ebp + 8] ; 1st argument the function pointer %define x dword [ebp + 12] ; 2nd argument the value to compute %define e dword [ebp + 16] ; 3rd argument user specified percision %define fresult dword [ebp - 4] ; 1st local var stores f(x) value %define h dword [ebp - 8] ; 2nd local var stores h %define param dword [ebp - 12] ; 3rd local var stores x + h %define two dword [ebp - 16] ; 4th local var stores integer 2 %define diff dword [ebp - 20] ; 5th local var stores (f(x+h)-f(x))/h %define tmp dword [ebp - 24] ; 6th local var a temp space for diff segment .text global compute_derivative compute_derivative: push ebp ; setup mov ebp, esp ; setup sub esp, 24 ; setup spare space for 6 local vars push x ; push x as f's param call f ; call f add esp, 4 ; clean up stack after function call fstp fresult ; store f(x) value into fresult mov two, 2 ; store 2 in a four byte quatity mov h, 2 ; initialize h, it will be divided by 2 mov diff, 0 ; initialize diff fild h ; convert h into a float quantity fstp h compute_loop: fld h ; st0 = h_old fidiv two ; st0 = h_old/2 fst h ; h_new = h_old/2 fadd x ; st0 = h_new + x fstp param ; fp stack is empty at this point push param ; call f with h_new + x call f add esp, 4 ; clean up stack after function call fsub fresult ; st0 = f(h_new + x) - f(x) fdiv h ; st0 = (f(h_new + x) - f(x))/h fabs ; |st0 = (f(h_new + x) - f(x))/h| fst tmp ; store the diff_new in tmp for now fsub diff ; st0 = diff_old - diff_new fabs ; st0 = |diff_old - diff_new| fcomp e ; compare st0 with epsilon fstsw ax sahf jna compute_loop_end ; jmp to terminate if st0 < epsilon fld tmp ; otherwise diff_new = tmp fstp diff jmp compute_loop compute_loop_end: fld tmp ; put diff_new as the return value add esp, 24 mov esp, ebp ; clean up pop ebp ; clean up ret ; clean up