In this page, it's written that a tail-call is when a call occurs in the end of a function. This is incorrect, a tail-call is when, in assembly, a CALL occurs before RET.

Code: Select all

```
unsigned long long Factorial(unsigned start) {
if (start > 1) {
return Factorial(start - 1) * start;
} // if
return 1;
} // Factorial(start)
```

Now the page also writes:

Code: Select all

```
unsigned long long Factorial(unsigned start) {
if (start <= 1) {
return 1;
} // if
return start * Factorial(start - 1);
} // Factorial(start)
```

Code: Select all

```
CMP start,1
JMP.HI _endofblock
MOV return_value, 1
RET
_endofblock:
SUB tmp, start, 1
PUSH tmp
CALL Factorial
MUL return_value, return_value, start
RET
```

Now an example of a tail-call would include:

Code: Select all

```
function foo(data) {
a(data);
return b(data);
}
```

Code: Select all

```
PUSH data
CALL a
PUSH data #assuming this is needed
CALL b
RET
```

Code: Select all

```
PUSH data
CALL a
PUSH data #assuming this is needed
JMP b
```

Contrary to what the said page claims, a tail call doesn't need to be at the tail of the code:

Code: Select all

```
function bar(data) {
if ( a(data) ) {
return b(data);
}
return c(data);
}
```

Code: Select all

```
PUSH data
CALL a
TEST return_value
JMP.FALSE _endofblock
PUSH data
CALL b
RET
_endofblock:
PUSH data
CALL c
RET
```

Code: Select all

```
PUSH data
CALL a
TEST return_value
JMP.FALSE _endofblock
PUSH data
JMP b
_endofblock:
PUSH data
JMP c
```

Code: Select all

```
function foo()
{
int myInteger = bar();
return myInteger;
}
```

Code: Select all

```
CALL bar
MOV myInteger, return_value
MOV return_value, myInteger
RET
```

Code: Select all

```
CALL bar
RET
```

Code: Select all

`JMP bar`

Code: Select all

```
unsigned long long Factorial(unsigned start) {
if (start <= 1) {
return 1;
} // if
return start * Factorial(start - 1);
} // Factorial(start)
```

Code: Select all

```
CMP start,1
JMP.HI _endofblock
MOV return_value, 1
RET
_endofblock:
SUB tmp, start, 1
PUSH tmp
CALL Factorial
MUL return_value, return_value, start
RET
```

Now of course, this also depends on the exact architecture, but as I said, the way the instructions CALL, RET and JMP work are usually the same, so most of the above examples with pseudo-assembly would still work on most real architectures.

If you, the person reading this, are a moderator or anyone else with the privilege to modify the wiki, I ask of you to correct this page, please. Thanks in advance.

Source: https://en.wikipedia.org/wiki/Tail_call