Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Tail call
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
===In assembly=== {{unreferenced section|date=June 2014}} Tail calls are often optimized by [[interpreter (computing)|interpreters]] and [[compiler]]s of [[functional programming]] and [[logic programming]] languages to more efficient forms of [[iteration]]. For example, [[Scheme (programming language)|Scheme]] programmers commonly express [[while loop]]s as calls to procedures in tail position and rely on the Scheme compiler or interpreter to substitute the tail calls with more efficient [[jump (computer science)|jump]] instructions.<ref>{{cite web | url=https://gcc.gnu.org/ml/gcc/2000-07/msg00595.html | title=proper tail recursion for gcc | publisher=GCC Project | date=20 July 2000 | access-date=10 March 2015 | author=Probst, Mark}}</ref> For compilers generating assembly directly, tail-call elimination is easy: it suffices to replace a call opcode with a jump one, after fixing parameters on the stack. From a compiler's perspective, the first example above is initially translated into pseudo-[[assembly language]] (in fact, this is valid [[x86 assembly language|x86 assembly]]): <syntaxhighlight lang="asm"> foo: call B call A ret </syntaxhighlight> Tail-call elimination replaces the last two lines with a single jump instruction: <syntaxhighlight lang="asm"> foo: call B jmp A </syntaxhighlight> After subroutine <code>A</code> completes, it will then return directly to the return address of <code>foo</code>, omitting the unnecessary <code>ret</code> statement. Typically, the subroutines being called need to be supplied with [[parameter (computer science)|parameter]]s. The generated code thus needs to make sure that the [[call frame]] for A is properly set up before jumping to the tail-called subroutine. For instance, on [[computing platform|platform]]s where the [[call stack]] does not just contain the [[return statement|return address]], but also the parameters for the subroutine, the compiler may need to emit instructions to adjust the call stack. On such a platform, for the code: '''function''' foo(data1, data2) B(data1) '''return''' A(data2) (where <code>data1</code> and <code>data2</code> are parameters) a compiler might translate that as:{{efn| The <code>call</code> instruction first pushes the current code location onto the stack and then performs an unconditional jump to the code location indicated by the label. The <code>ret</code> instruction first pops a code location off the stack, then performs an unconditional jump to the retrieved code location. }} <syntaxhighlight lang="nasm" line> foo: mov reg,[sp+data1] ; fetch data1 from stack (sp) parameter into a scratch register. push reg ; put data1 on stack where B expects it call B ; B uses data1 pop ; remove data1 from stack mov reg,[sp+data2] ; fetch data2 from stack (sp) parameter into a scratch register. push reg ; put data2 on stack where A expects it call A ; A uses data2 pop ; remove data2 from stack. ret </syntaxhighlight> A tail-call optimizer could then change the code to: <syntaxhighlight lang="nasm" line> foo: mov reg,[sp+data1] ; fetch data1 from stack (sp) parameter into a scratch register. push reg ; put data1 on stack where B expects it call B ; B uses data1 pop ; remove data1 from stack mov reg,[sp+data2] ; fetch data2 from stack (sp) parameter into a scratch register. mov [sp+data1],reg ; put data2 where A expects it jmp A ; A uses data2 and returns immediately to caller. </syntaxhighlight> This code is more efficient both in terms of execution speed and use of stack space.
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)