Recursion: Tail recursion optimization from the perspective of Assembly

Source: Internet
Author: User
For tail recursion, many people's understanding is limited to its combination of recursion and tail call, which is more efficient than normal recursion. As for why efficiency is high and where it is high, it may not be further explored. When executing function B, most of the stack frames of function A are useless and can be modified or overwritten. This can be used by the compiler to optimize the function. After function B is executed, it is directly returned to the caller of function.

For tail recursion, many people's understanding is limited to its combination of recursion and tail call, which is more efficient than normal recursion. Why is efficiency high .?

End call

To say tail recursion, we must first talk about tail calling. I understand that the end call is probably like this:

  1. Function A Calls function B.
  2. Function A returns immediately after Function B is executed.
  3. That is to say, calling function B (and returning execution results) is the last thing function A does.
  4. After function B is executed, function A is executed.

Therefore, when executing function B, most of the stack frames of function A are useless and can be modified or overwritten. This can be used by the compiler for optimization. After function B is executed, it is directly returned to the caller of function .?

Here, we need to note that it comes from compiler optimization .? This optimization may be of little significance for general tail calls, but it is very important for tail recursion .?

Tail recursion

Tail recursion is A kind of recursion based on the form of tail call, which is equivalent to function B as mentioned above .?

Some problems with normal recursion are that each layer of recursion consumes a certain amount of stack space. too deep recursion may also cause Stack Overflow and function calls, avoiding pushing to pop, consumed time .?

The tail call is used to implement recursion, that is, tail recursion, which can theoretically solve the problem of normal recursion. Because the stack frames used by the next layer of recursion can overlap with the previous layer (implemented using jmp), local variables can be reused without consuming additional stack space, no push or pop .?

Again, the actual effect of it comes from the optimization of the compiler ). When tail recursion is used, the compiler will optimize recursive calls into loops if it finds it appropriate. Currently, most compilers support tail recursion optimization. Some languages are even very dependent on tail recursion (tail call), such as erlang or other functional languages (it is said that they are used to better process the continuation-passing style ).?

If there is no optimization, there is no advantage in tail recursion for function calling, and there are even disadvantages-the code is not intuitive to write .?

The optimization capabilities of modern compilers are very powerful. in many cases, the compiler is not very soft (so it has volatile ). But sometimes the compiler is very proud. you need to give it a signal to optimize it. Tail recursion is equivalent to passing a signal to the compiler. how can I optimize it !?

Test

To verify tail recursion optimization, you can write a small program for testing. In VS2010, the/O1 or above optimization options will be used, and the tail recursive optimization will generally be performed. In Gcc3.2.2 (old version), The-O2 optimization option is generally used.

First, let's look at normal recursion:

// Recursive int factorial (int n) {if (n <= 2) {return 1;} else {return factorial (n-1) + factorial (n-2 );}}

Its assembly code:

00401371push   %ebp00401372mov    %esp,%ebp00401374push   %ebx00401375sub    $0x14,%esp00401378cmpl   $0x2,0x8(%ebp)0040137Cjg     0x401385 
 
  0040137Emov    $0x1,%eax00401383jmp    0x4013a4 
  
   00401385mov    0x8(%ebp),%eax00401388dec    %eax00401389mov    %eax,(%esp)0040138Ccall   0x401371 
   
    00401391mov    %eax,%ebx00401393mov    0x8(%ebp),%eax00401396sub    $0x2,%eax00401399mov    %eax,(%esp)0040139Ccall   0x401371 
    
     004013A1lea    (%ebx,%eax,1),%eax004013A4add    $0x14,%esp004013A7pop    %ebx004013A8leave004013A9ret
    
   
  
 

In the positions of 0040138C and 0040139C, we can see that recursion still uses the call Command. how does tail recursion deal with the assembly angle?

Tail recursion:

int factorial_tail(int n,int acc1,int acc2){    if (n < 2)    {        return acc1;    }    else    {        return factorial_tail(n-1,acc2,acc1+acc2);    }}

Its assembly code:

00401381push   %ebp00401382mov    %esp,%ebp00401384sub    $0x18,%esp00401387cmpl   $0x1,0x8(%ebp)0040138Bjg     0x401392 
 
  0040138Dmov    0xc(%ebp),%eax00401390jmp    0x4013b2 
  
   00401392mov    0x10(%ebp),%eax00401395mov    0xc(%ebp),%edx00401398lea    (%edx,%eax,1),%eax0040139Bmov    0x8(%ebp),%edx0040139Edec    %edx0040139Fmov    %eax,0x8(%esp)004013A3mov    0x10(%ebp),%eax004013A6mov    %eax,0x4(%esp)004013AAmov    %edx,(%esp)004013ADcall   0x401381 
   
    004013B2leave004013B3ret
   
  
 

In the 00401390 position, tail recursion directly uses jmp for loop jump.

How to view the C language program assembly? Let's take a look at this separate article: how to view the assembly Code of the program under Code: Blocks

Additional reading

The topic list of this article is as follows:

  1. Recursive: recursive thinking
  2. Recursion: two conditions that must be met by recursion
  3. Recursion: recursive determination of string-to-text phenomena
  4. Recursive: recursive implementation of binary search algorithms
  5. Recursion: the efficiency of recursion
  6. Recursion: recursion and loop
  7. Let's talk about recursion: Is loop and iteration the same thing?
  8. Recursive computing and iterative computing
  9. On Recursion: Learn about tail recursion from Fibonacci
  10. Recursive: Tail recursion and CPS
  11. Recursion: add more knowledge about Continuation.
  12. Recursion: Tail recursion in PHP and its optimization
  13. Recursion: Tail recursion optimization from the perspective of Assembly

This article is available at http://www.nowamagic.net/librarys/veda/detail/2336.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.