由变态C自增所想到的

 前面转载了[变态的C自增]这篇文章后,自己又总结了一下关键点:

1、局部变量i,是保存在栈上的,没有拷贝!
2、后缀++,和前缀++的求值时间的先后问题

3、后缀++的使用甚至在"="赋值操作之后。
但是,上述文章并没有对gcc和vc进行分析。在两个变量进行运算的时候,两者的代码运算的结果还是一致的。当多于两个变量运算的时候,结果就出现分歧了。

 

代码如下:

#include<stdio.h>

int main()
{
        int a = 3;

        a = ++a*++a*++a;
        printf("%d/n",a);
        return 0;
}

 

 

0040D76B   add         ecx,1
0040D76E   mov         dword ptr [ebp-4],ecx
0040D771   mov         edx,dword ptr [ebp-4]
0040D774   imul        edx,dword ptr [ebp-4]
0040D778   mov         eax,dword ptr [ebp-4]
0040D77B   add         eax,1
0040D77E   mov         dword ptr [ebp-4],eax
0040D781   imul        edx,dword ptr [ebp-4]
0040D785   mov         dword ptr [ebp-4],edx
先加二次,此时a=5,然后5*5=25  --> edx

a又加一,a=6.最后执行edx与a所在地址的值相乘,即25*6=150

 

VS2008的汇编代码如下:

004113C5  mov         eax,dword ptr [a]
004113C8  add         eax,1                               
004113CB  mov         dword ptr [a],eax
004113CE  mov         ecx,dword ptr [a]
004113D1  add         ecx,1
004113D4  mov         dword ptr [a],ecx
004113D7  mov         edx,dword ptr [a]
004113DA  add         edx,1
004113DD  mov         dword ptr [a],edx
004113E0  mov         eax,dword ptr [a]
004113E3  imul        eax,dword ptr [a]
004113E7  imul        eax,dword ptr [a]
004113EB  mov         dword ptr [a],eax

连续加了三次,此时a=6,然后6*6*6=216  --> [a]地址所存放在的地方

 

gcc4.3.2的汇编代码如下:

        movl    $3, -8(%ebp)
        addl    $1, -8(%ebp)
        addl    $1, -8(%ebp)
        movl    -8(%ebp), %eax
        movl    %eax, %edx
        imull   -8(%ebp), %edx
        addl    $1, -8(%ebp)
        movl    -8(%ebp), %eax
        imull   %edx, %eax
        movl    %eax, -8(%ebp)

与vc6.0的相似,a的值存放的位置是[ebp-8]的地方,然后自增二次,此时a=5.然后相乘结果放到edx中.a又自增,此时a=6,相乘的结果放到eax中,然后赋值给[ebp-8](即文中的-8(%ebp)).a的值即为5*5*6=150.

 

PS:微软真是强大,VS2008连具体变量的地址都不让我看了.文中,我只是分析了关键部分的代码,其它部分的代码并未分析.下一阶段重点分析这一部分,即例程的prolog(序幕)与epilog(收尾)工作.

     此外,自增自减无非是编译器的具体实现问题,无需要太过纠结.

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章