递归汇编代码规律的总结:

递归汇编代码规律的总结:

Dump of assembler code for function func4:
   0x08048c4f <+0>:	sub    esp,0x1c							%开辟栈空间
   0x08048c52 <+3>:	mov    DWORD PTR [esp+0x10],ebx			
   0x08048c56 <+7>:	mov    DWORD PTR [esp+0x14],esi
   0x08048c5a <+11>:	mov    DWORD PTR [esp+0x18],edi		%edi初值是0,eax初值是外部传入
   0x08048c5e <+15>:	mov    esi,DWORD PTR [esp+0x20]		%传入第一个参数
   0x08048c62 <+19>:	mov    ebx,DWORD PTR [esp+0x24]		%传入第二个参数
   0x08048c66 <+23>:	test   esi,esi						
   %如果esi非正数则跳转,return eax = ebx = 0
   0x08048c68 <+25>:	jle    0x8048c95 <func4+70>
   0x08048c6a <+27>:	cmp    esi,0x1
   %如果参数esi等于1跳转,return eax = ebx
   0x08048c6d <+30>:	je     0x8048c9a <func4+75>

   0x08048c6f <+32>:	mov    DWORD PTR [esp+0x4],ebx
   %传入参数ebx,这个值没有改变
   0x08048c73 <+36>:	lea    eax,[esi-0x1]
   0x08048c76 <+39>:	mov    DWORD PTR [esp],eax
   %传入参数eax = esi - 1,调用函数func4(s-1,b)
   0x08048c79 <+42>:	call   0x8048c4f <func4>

   0x08048c7e <+47>:	lea    edi,[eax+ebx*1]
   %d = func4(s-1,b) + b
   0x08048c81 <+50>:	mov    DWORD PTR [esp+0x4],ebx
   %传入参数ebx,这个值没有改变
   0x08048c85 <+54>:	sub    esi,0x2
   0x08048c88 <+57>:	mov    DWORD PTR [esp],esi
   %传入参数esi - 2,调用函数func(s-2,b)
   0x08048c8b <+60>:	call   0x8048c4f <func4>

   0x08048c90 <+65>:	lea    ebx,[edi+eax*1]
   %这里的计算其实就是在计算返回值eax,b = d + func4(s-2,b) = func4(s-1,b) + b + func4(s-2,b)
   0x08048c93 <+68>:	jmp    0x8048c9a <func4+75>
   0x08048c95 <+70>:	mov    ebx,0x0
   0x08048c9a <+75>:	mov    eax,ebx
   %返回的eax的值其实就是ebx,a = b = func4(s-1,b) + b + func4(s-2,b)
   0x08048c9c <+77>:	mov    ebx,DWORD PTR [esp+0x10]
   0x08048ca0 <+81>:	mov    esi,DWORD PTR [esp+0x14]
   0x08048ca4 <+85>:	mov    edi,DWORD PTR [esp+0x18]
   0x08048ca8 <+89>:	add    esp,0x1c
   0x08048cab <+92>:	ret  

递归的汇编代码的讨论:

递归分为以下四步:

  1. 传递参数
  2. 调用自身函数
  3. 对函数进行数学运算
  4. 返回

下面一个形象的例子以及本题的例子来展示:

在这里插入图片描述

0x08048c6f <+32>:	mov    DWORD PTR [esp+0x4],ebx
%传入参数ebx,这个值没有改变
0x08048c73 <+36>:	lea    eax,[esi-0x1]
0x08048c76 <+39>:	mov    DWORD PTR [esp],eax
%传入参数eax = esi - 1,调用函数func4(s-1,b)
0x08048c79 <+42>:	call   0x8048c4f <func4>

%以上数传递参数以及函数自身调用

0x08048c7e <+47>:	lea    edi,[eax+ebx*1]

%d = func4(s-1,b) + b,有些数学运算不像前面的例子那么简单,通常可能多次调用,这里就是

以下是第二次调用,老套路先传递参数

0x08048c81 <+50>:	mov    DWORD PTR [esp+0x4],ebx
%传入参数ebx,这个值没有改变
0x08048c85 <+54>:	sub    esi,0x2
0x08048c88 <+57>:	mov    DWORD PTR [esp],esi
%传入参数esi - 2,调用函数func(s-2,b)
0x08048c8b <+60>:	call   0x8048c4f <func4>

%第二次调用函数自身

0x08048c90 <+65>:	lea    ebx,[edi+eax*1]

%这里的计算其实就是在计算返回值eax,b = d + func4(s-2,b) = func4(s-1,b) + b + func4(s-2,b)

%最后一句是跳转到递归返回return的位置,所以就是直接return计算结果(如果func4+75没有其他对eax进行操作的时候)

0x08048c93 <+68>:	jmp    0x8048c9a <func4+75>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

call me Patrick

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值