RET
The ret
instruction is used at the end of a procedure to return control back to the calling function. It works by popping the return address, which was saved on the stack by the call
instruction, into the instruction pointer rip
. This restores execution to the instruction immediately following the original call
. Without ret
, the program would not know where to continue after finishing a procedure, breaking the structured flow of execution.
section .data
message db "Fibonacci Sequence:", 0x0a
msg_len equ $ - message ; $ is the current address, so $ - message = length
section .text
global _start
_start:
;The call instruction pushes the return address—the address of the instruction
;immediately following the call—onto the stack and then jumps directly to the
;target procedure to begin execution. When the procedure completes, the ret
;instruction is executed, which pops the saved return address from the stack into
;rip, restoring program execution to the point immediately after the original call.
call printMessage ; print intro message
call initFib ; set initial Fib values
call loopFib ; calculate Fib numbers
call Exit ; Exit the program
printMessage:
mov rax, 1 ; rax: syscall number 1
mov rdi, 1 ; rdi: fd 1 for stdout
mov rsi,message ; rsi: pointer to message
mov rdx, msg_len ; length calculated dynamically with equ
;mov rdx, 20 ; rdx: print length of 20 bytes
syscall ; call write syscall to the intro message
ret
initFib:
xor rax, rax ; initialize rax to 0
xor rbx, rbx ; initialize rbx to 0
inc rbx ; increment rbx to 1
ret
loopFib:
add rax, rbx ; get the next number
xchg rax, rbx ; swap values
cmp rbx, 10 ; do rbx - 10
js loopFib ; jump if result is <0
ret
; The ret instruction is not used in the Exit procedure because the goal is to
; terminate the program rather than return to the calling point. Using ret would pop
; a return address from the stack and continue execution, but since the program is
; finished, we instead use the exit syscall (e.g., rax = 60 on Linux x86-64) to end
;the program cleanly and hand control back to the operating system.
Exit:
mov rax, 60
mov rdi, 0
syscall
* The call instruction saves the address of the next instruction (the current value of
rip) onto the stack and then jumps to the specified procedure. Once the procedure
completes, the ret instruction pops the saved address from the top of the stack back
into rip, returning execution to the point immediately following the original call.
Together, call and ret provide a structured mechanism for function and procedure
calls in assembly, enabling nested calls, recursion, and proper program flow control.
VISUALIZATION
Program start: _start
Stack (top at bottom of diagram):
Empty
_start calls printMessage
Push return address of _start+next_instruction onto stack
+--------------------+ <- rsp
| return to _start |
+--------------------+
Inside printMessage, syscall executes
ret pops return address from stack
Stack after ret from printMessage
(empty)
_start calls initFib
Push return address of _start+next_instruction onto stack
+--------------------+
| return to _start |
+--------------------+
Inside initFib
ret pops return address from stack
Stack after ret from initFib
(empty)
_start calls loopFib
Push return address of _start+next_instruction onto stack
+--------------------+
| return to _start |
+--------------------+
Inside loopFib
(ret inside loop after finishing calculation)
ret pops return address from stack
Stack after ret from loopFib
(empty)
_start calls Exit
Push return address of _start+next_instruction onto stack
Inside Exit, syscall 60 terminates program
Stack is no longer used
Last updated