由變態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(收尾)工作.

     此外,自增自減無非是編譯器的具體實現問題,無需要太過糾結.

 

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