Skip to main content

Функции

Функция - набор инструкций под некоторой меткой (имя функции). Функции завершается 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

Функции могут использовать регистры. Поэтому нужно сохранять нужные регистры перед вызовом функций. 

Для передачи параметров применяются регистры, стек или через глобальные переменные. Если параметров немного, то через регистры.