What does it mean when a function ends with jmp <function> instead of call <function> + ret?
It's a tail call: instead of call + ret, the function jmps straight to the callee, which then returns directly to the original caller — reusing the current return address and stack frame.
* A tail call replaces call+ret with a jmp; the callee reuses the return address and returns straight to the original caller. *
my_func:
# setup arguments
mov %rbx, %rdi
pop %rbx
jmp <other_func>
Instead of:
mov %rbx, %rdi
pop %rbx
call <other_func>
ret
Why: When the last thing a function does is call another function and return its result, the call + ret is wasteful. jmp reuses the current return address — when other_func returns, it goes directly back to the original caller.
How to spot it: A jmp to a named function (not a local label) near the end of a function, after the epilogue (pop/add) but with no ret.
Note: Don't confuse this with a loop. If the jmp target is a different function (not a label within the current function), it's a tail call.
Go deeper: