Функции
Функция - набор инструкций под некоторой меткой (имя функции). Функции завершается ret. Вызываемые функции могут вызывать другие функции.
sum:
mov rdi, 7
mov rsi, 5
add rdi, rsi
ret
Вызов функции:
call название_функции
Call помещает в стек 64-битный адрес инструкции, которая идет сразу после вызова. Это называется адресом возврата. Когда процедура завершает выполнение, для возвращения к вызывающему коду она выполняет инструкцию ret. Команда ret извлекает 64-битный адрес возврата из стека и косвенно передает управление на этот адрес.
global _start
section .text
_start:
call sum
mov rax, 60
syscall
sum:
mov rdi, 7
mov rsi, 5
add rdi, rsi
ret
Стек и функции
При вызове ret на верхушке стека должен быть адрес возврата. Иначе скорее всего будет ошибка "Segmentation fault":
Поэтому процедура должна извлекать из стека все ранее сохраненные в ней данные и извлекать ровно столько, сколько было сохранено, чтобы адрес возврата сохранялся в стеке и к концу программы оказался в верхушке стека.
Можно использовать этот адрес для выхода из функции:
global _start
section .text
_start:
mov rdi, 5
mov rsi, 20
call sum
add rdi, 10 ; RDI = 15
mov rax, 60
syscall
; определяем функцию sum
sum:
jmp [rsp] ; переходим по адресу, который храниться в RSP
add rdi, rsi ; эта строка НЕ выполняется
ret
Функции могут использовать регистры. Поэтому нужно сохранять нужные регистры перед вызовом функций.
Для передачи параметров применяются регистры, стек или через глобальные переменные. Если параметров немного, то через регистры.