我用C写了一个很小的程序:
- C/C++ code
int f(int i){ if(i>1)return i+f(i-1); else return 1;}int g(int i){ if(i==1)return 1; else return i+f(i-1);} int main(void){ int fi=f(5); int gi=g(7); printf("%d,%d\n",fi,gi); return 0;}
用VC10编译release版,我发现反汇编是这样的:
- Assembly code
int main(void){ int fi=f(5);00401030 push 4 ;为什么是push 4? 我的参数是5啊!!!!!!!00401032 call f (401000h) int gi=g(7);00401037 push 5 ;为什么是push 5? 我的参数是7啊!!!!!!!00401039 lea ecx,[eax+5] 0040103C call f (401000h) 00401041 add eax,0Dh printf("%d,%d\n",fi,gi);
我的问题是: g(7)函数调用的参数7去哪里了? 看起来像是[eax+5]里面保存的。但是eax不是保存返回地址的么? 而且,x86下面的整数数应该按照4字节对齐啊,这个eax+5计算出来的是一个奇数地址吧?
真是奇怪了。各位大侠帮忙解释一下?
------解决方案--------------------------------------------------------
没看懂,等高手
个人感觉是把那些函数当内联函数处理了
------解决方案--------------------------------------------------------
结贴率太低
------解决方案--------------------------------------------------------
没有内联。
int main(void){
int fi=f(5);
00401030 push 4
00401032 call f (401000h) // eax = f(4)
int gi=g(7);
00401037 push 5
00401039 lea ecx,[eax+5] // ecx = f(4) + 5 = f(5)
0040103C call f (401000h) // eax = f(5)
00401041 add eax,0Dh // eax = f(5) + 6 + 7 = f(7)
printf("%d,%d\n",fi,gi);
总之这个优化的方法是很奇怪的,有那么一点优化,又不是很优化。既然f(5)在ecx中已经计算出来了,那么f(7)就可以直接ecx + 6 + 7了,何必再调用一次f(5)呢???或者直接优化成1+2+3+4+5、1+2+3+4+5+6+7呢?
------解决方案--------------------------------------------------------
功能合并了。
------解决方案--------------------------------------------------------
f和g只有在输入参数为负的情况下结果不同,大于等于零的情况下是一样的。
------解决方案--------------------------------------------------------