/********************015.c do-while语句*************************
* C语言精彩编程百例的第15个例子
* 计算sin(x)=x-x^3/3!+x^5/5!-x^7/7!+... 直到最后一项小于1e-7为止
* 这个是利用泰勒展开求sin(x)值的例子,教材里没有说明的是:
* 泰勒展开的这一公式:F(N+1)=-F(N)*X*X/(2N*(2N+1)),,F1=X
* 这个是程序编写的关键。
*/
#include <math.h>
#include <stdio.h>
void main()
{
//用s表示多项式的值,用t表示每一项的值
double s,t,x;
int n;
printf("please input x:");
scanf("%lf",&x);
//赋初值
t=x;
n=1;
s=x;
//进行叠加运算
do
{
n=n+2;
t=t*(-x*x)/((float)(n)-1)/(float)(n);
s=s+t;
}while(fabs(t)>=1e-8);
printf("sin(%f)=%lf\n",x,s);
}
对应的汇编部分
subl $12, %esp
pushl $LC0 # printf
call _printf
addl $16, %esp
subl $8, %esp # scanf
leal -24(%ebp), %eax
pushl %eax
pushl $LC1
call _scanf
addl $16, %esp
movl -24(%ebp), %eax # eax=x低32位
movl -20(%ebp), %edx # edx=x高32位
movl %eax, -16(%ebp) # t=x低32位
movl %edx, -12(%ebp) # t=x高32位
movl $1, -28(%ebp) # n=1
movl -24(%ebp), %eax # eax=x低32位
movl -20(%ebp), %edx # edx=x高32位
movl %eax, -8(%ebp) # s=x高32位
movl %edx, -4(%ebp) # s=x高32位
L34:
leal -28(%ebp), %eax # eax=&n
addl $2, (%eax) # n=n+2
movl -24(%ebp), %eax # eax=x低32位
movl -20(%ebp), %edx # edx=x高32位
movl %eax, -40(%ebp)
movl %edx, -36(%ebp)
fldl -40(%ebp) # 加载浮点数x到FPU
fchs # 改变符号位 -x
fmull -24(%ebp) # -x*x
fmull -16(%ebp) # -x*x*t
fildl -28(%ebp) # 装入整数i 到st(0)
fld1 # FLD1 将1.0装入st(0)
fsubrp %st, %st(1) # st1-st 然后执行一次出栈操作
fdivrp %st, %st(1) # st1/st
fildl -28(%ebp) # 装入整数i 到st(0)
fdivrp %st, %st(1) # st1/st
fstpl -16(%ebp) # FSTP dest dest <- st(0) (mem32/mem64/mem80);然后再执行一次出栈操作
fldl -8(%ebp) # 装入s 到st
faddl -16(%ebp) # s+t
fstpl -8(%ebp) # s=s+t
subl $8, %esp # 准备调用fabs
pushl -12(%ebp)
pushl -16(%ebp)
call _fabs
addl $16, %esp
fldl LC3
fxch %st(1) #FXCH 交换指令,交换st(0)和st(1)的值 st(0) <-st(1)
fucompp #FUCOMPP st(i) 比较st(0) 和st(i),并且执行两次出栈操作
fnstsw %ax #用FNSTSW把FPU状态字送到AX,用了FNSTSW后与跳转有关的那几个标志都在AH里
testb $5, %ah #设置状态标志
je L34 #判断条件符合跳转执行下一次循环
subl $12, %esp
pushl -4(%ebp)
pushl -8(%ebp)
pushl -20(%ebp)
pushl -24(%ebp)
pushl $LC4
call _printf
addl $32, %esp
leave
ret