вызов помещает текущее значение регистра RIP (адрес возврата) в стек + выполняет вызов
ret извлекает адрес возврата (который call нажат) с вершины стека (там есть регистры RSP) и записывает его в регистр RIP.
Пример для блока GNU / Linux: функция f вызывает функцию g и позволяет взглянуть на кадр g.
НИЗКИЙ АДРЕС
... <- RSP (указатель стека показывает вершину стека) регистрирует точки по этому адресу <br>
местные г
Базовый указатель f (старое значение RBP) <- регистр RBP (базовый указатель) указывает на этот адрес <br>
ret адрес f (старое значение RIP) (это то, что вызов (из f) выдвинул, и что ret (из g) выскочит)
аргументы, которые f вызвала g с и не вписались в регистры (я думаю, что в Windows это не так)
...
ВЫСОКИЙ АДРЕС
g освободит локальные переменные (movq% rsp,% rbp)
g выведет «старый RBP» и сохранит его в регистре RBP (pop% rbp)
g будет ret , который изменит RIP со значением, которое хранится там, где RSP указывает на
Надеюсь, это поможет