- 1 int fib_w(int n)
- 2 {
- 3 int i = 1;
- 4 int val = 1;
- 5 int nval = 1;
- 6
- 7 while (i<n) {
- 8 int t = val+nval;
- 9 val = nval;
- 10 nval = t;
- 11 }
- 12
- 13 return val;
- 14 }
- 15
在这里,所使用的编译平台是IA32下的GCC(version 3.2),我自己做实验的时候机器平台是(Windows XP Mingw-gcc 4.3.2)
首先来一段很简单的C程序:
这段代码 描述的是 计算第N项fibonacci(菲波那西数列)的值.
有关fibonacci的介绍:
这个数列是意大利中世纪数学家斐波那契在<算盘全书>中提出的,这个级数的通项公式,除了具有a(n+2)=an+a(n +1)/的性质外,还可以证明 通项公式为:an=1/√[(1+√5/2) n-(1-√5/2) n](n=1,2,3.....) 这个通项公式中虽然 所有的an都是正整数,可是它们却是由一些无理数表示 出来的。
运行GCC

生成GUN汇编代码(GAS)
1 movl 8(%ebp), %eax
2 movl $1,%ebx
3 movl $1,%ecx
4 cmpl %eax,%ebx
5 jge .L9
6 leal -1(%eax),%edx
7 .L10:
8 leal (%ecx,%ebx),%eax
9 movl %ecx,%ebx
10 movl %eax,%eax
11 decl %edx
12 jnz .L10
13 .L9:
14
15 ---------------------------------------------------------
16 省略栈创建代码
上述代码 转换成某种扩展的C之后,是这样的2 movl $1,%ebx
3 movl $1,%ecx
4 cmpl %eax,%ebx
5 jge .L9
6 leal -1(%eax),%edx
7 .L10:
8 leal (%ecx,%ebx),%eax
9 movl %ecx,%ebx
10 movl %eax,%eax
11 decl %edx
12 jnz .L10
13 .L9:
14
15 ---------------------------------------------------------
16 省略栈创建代码
1
int fib_w_goto(int n)
2

{
3
int val=1;
4
int nval=1;
5
int nmi ,it;
6
7
if (val >= n)
8
goto done;
9
nmi = n-1;
10
11
loop:
12
t = val+nval;
13
val = nval;
14
nval = t;
15
nmi--;
16
if(nmi)
17
goto loop;
18
19
done:
20
return val;
21
}

2



3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

这里用了不推荐使用的goto语句是为了清晰的表明gcc汇编代码的处理过程.我们可以发现对于






而且我们发现这里,并没有出现我们一开始设置的变量i,而是出现了一个nmi的新变量,她的指等于n-i;这使得编译器只使用
三个寄存器作为循环变量,而不是原来的四个寄存器;其次,他把初始判定(i<n)优化成了(val<n),这样i就彻底消失了,这在编译器中是很常见的。最后,为了循环的连续执行,要保证i<=n,这样编译器就假设nmi是非负的了.因此只需要将nmi!=0。这样就在汇编中又少了一条指令.