汇编代码分析及注释:
phase_4函数:
func4函数:
思考过程:
首先,查看0x804a3ef地址中放的是%d,%d,可知此题是输入两个数字。
可判断有一个参数是输入的,另一个是指定的6
8048dea: 8b 44 24 18 mov 0x18(%esp),%eax
` 8048dee: 89 44 24 04 mov %eax,0x4(%esp) //将eax作为func4函数的参数2`
` 8048df2: c7 04 24 06 00 00 00 movl $0x6,(%esp) //将6作为func4函数的参数1`
8048df9: e8 65 ff ff ff call 8048d63 <func4> //调用func4函数
通过观察发现phase 4的过程是输入两个数(y, x),然后调用一个函数func4(6, x),判断y 是否等于这个函数的返回值。如果不是,则爆炸。根据下面代码可知,输入x 必须大于2,我们假设输入的是x=3。
` 8048de0: 83 f8 02 cmp $0x2,%eax `
` 8048de3: 76 05 jbe 8048dea <phase_4+0x3d>`
观察分析func4函数递归部分,发现它有两个自身的调用。转换为c语言可如此表示。
int func4(int y, int x) {
if (y <= 0) return 0;
if (y == 1) return x;
return func4(x, y - 1) + x + func4(x, y - 2);
}
递归条件:
` 8048d71: 85 db test %ebx,%ebx //参数1,ebx为0跳转,类似于递归的结束`
` 8048d73: 7e 2c jle 8048da1 <func4+0x3e> `
` 8048d75: 89 f0 mov %esi,%eax //参数2,eax`
` 8048d77: 83 fb 01 cmp $0x1,%ebx //参数1,ebx为1,跳转到8048da6 `
` 8048d7a: 74 2a je 8048da6 <func4+0x43>`
递归调用
` 8048d80: 8d 43 ff lea -0x1(%ebx),%eax //参数1,减1`
8048d83: 89 04 24 mov %eax,(%esp)
` 8048d86: e8 d8 ff ff ff call 8048d63
` 8048d8b: 8d 3c 30 lea (%eax,%esi,1),%edi`
8048d8e: 89 74 24 04 mov %esi,0x4(%esp)
` 8048d92: 83 eb 02 sub $0x2,%ebx`
8048d95: 89 1c 24 mov %ebx,(%esp)
8048d98: e8 c6 ff ff ff call 8048d63 <func4> //第二个递归
总结分析
当x等于3时根据上面总结的递归代码,不难算出最后返回的结果为60,所以输入的两个数应该为60 ,3。