C----函数递归之反汇编
环境
win10
vc6.0
debug
代码
关于求阶层问题:n!=n(n-1)!;(n-1)! = (n-1)(n-2)!
例如5!=5(4)! 4!=43! 3!=32! 2!=21 函数递归的出口是1,所以函数递归最重要的条件是去寻找递归的出口
int fun(int i)
{
int sum = 0;
if (i == 1)
{
return 1;
}
else
{
sum = i*fun(i-1);
}
return sum ;
}
int main()
{
int n = 0;
printf("请输入你要求的阶层\r\n");
scanf("%d",&n);
int result1 = fun(n);
printf("%d",result1);
return 0;
}
关于调试去栈的问题
1.main栈
2.fun(0x00000005)栈 i=5;sum = 0
3.fun(0x00000004)栈 i=4;sum = 0
4.fun(0x00000003)栈 i=3;sum = 0
5.fun(0x00000002)栈 i=2;sum = 0
6.fun(0x00000001)栈 i=1;sum = 0
7.当 i = 1,sum=0时 走完if(i==1)时会走return 1 return之后直接走到fun的右括号,黄色箭头代表即将执行但还未执行的代码.
8.清理函数fun(0x00000001)栈空间并进入fun(0x00000002)的栈
9.执行完以后
sum=2;
10.清理函数fun(0x00000003)的栈
i=3 * fun(3-1) ==6 sum =6;
以此直到fun(0x00000005)的栈清理完为止
函数递归执行图
汇编代码分析
21: int main()
22: {
0040D790 55 push ebp
0040D791 8B EC mov ebp,esp
0040D793 83 EC 48 sub esp,48h
0040D796 53 push ebx
0040D797 56 push esi
0040D798 57 push edi
0040D799 8D 7D B8 lea edi,[ebp-48h]
0040D79C B9 12 00 00 00 mov ecx,12h
0040D7A1 B8 CC CC CC CC mov eax,0CCCCCCCCh
0040D7A6 F3 AB rep stos dword ptr [edi]
23: int n = 0;
0040D7A8 C7 45 FC 00 00 00 00 mov dword ptr [ebp-4],0 //[ebp-4]第一个局部变量 [ebp-8]就是代表第2个局部变量;[ebp-C]就是代表第3个局部变量以此类推
24: printf("请输入你要求的阶层\r\n");
0040D7AF 68 A4 2F 42 00 push offset string "\xc7\xeb\xca\xe4\xc8\xeb\xc4\xe3\xcf\xeb\xd2\xaa\xc7\xf3\xb5\xc4" (00422f
0040D7B4 E8 87 39 FF FF call printf (00401140)
0040D7B9 83 C4 04 add esp,4
25: scanf("%d",&n);
0040D7BC 8D 45 FC lea eax,[ebp-4]
0040D7BF 50 push eax
0040D7C0 68 1C 20 42 00 push offset string "%d" (0042201c)
0040D7C5 E8 16 22 00 00 call scanf (0040f9e0)
0040D7CA 83 C4 08 add esp,8
26: int result1 = fun(n);
0040D7CD 8B 4D FC mov ecx,dword ptr [ebp-4]
0040D7D0 51 push ecx
0040D7D1 E8 43 38 FF FF call @ILT+20(fun) (00401019)
0040D7D6 83 C4 04 add esp,4
0040D7D9 89 45 F8 mov dword ptr [ebp-8],eax
27: printf("%d",result1);
0040D7DC 8B 55 F8 mov edx,dword ptr [ebp-8]
0040D7DF 52 push edx
0040D7E0 68 1C 20 42 00 push offset string "%d" (0042201c)
0040D7E5 E8 56 39 FF FF call printf (00401140)
0040D7EA 83 C4 08 add esp,8
28: return 0;
0040D7ED 33 C0 xor eax,eax
29: }