Значение RET в сборке
Я очень новичок в сборке, и я не понимаю, что именно означает, когда в конце proc вы пишете число с помощью оператора ret
.
Вот так:
Function Proc
push ax cx
.
...body...
.
pop cx ax
ret 2
Function endp
Я понимаю, что это как-то связано с тем, куда указатель стека должен вернуться в конце функции?
Пожалуйста, это действительно помогло бы мне, если бы вы могли легко объяснить это.
Ответы
Ответ 1
Да, но ret 2
также удаляет из байта 2 байта параметров. Предположительно, ваша функция вызывалась как:
push some_parameter
call Function
В этот момент функция cdecl
- функция "очиститель звонящего" (обычно используется C) - потребовала бы add sp, 2
"очистить стек", удалив параметр. Такая функция завершится простым ret
.
Функция A stdcall
, которая есть у вас, - это функция "очистка отклонений" (используемая, например, Windows API), не требует add sp, 2
- она была выполнена с помощью ret 2
.
Если вы не знаете об этом, call
помещает обратный адрес в стек (и ret
выдает его), поэтому вы можете просто pop
получить параметр внутри вашей функции.
Ответ 2
Допустим, у меня есть процедура добавления двух слов и оставить сумму в EAX
. Слова являются аргументами, которые я хочу передать процедуре в стеке. то есть:
push word1
push word2
call addtwob
Процедура будет выглядеть примерно так:
addtwob proc
push ebp
mov ebp,esp
mov eax, [ebp+6]
add eax, [ebp+8]
pop ebp
ret 4
Endp
[ebp+6]
и [ebp+8]
адрес word2
и word1
в стеке.
ret 4
просто возвращается, как обычно, но затем добавляет 4 к указателю стека (esp
), поэтому вам не нужно pop word2
pop word1
покинуть стек после возврата из вызова, поэтому он очищает/балансирует стек без необходимо нажать предыдущие нажатия.
Ответ 3
Как сказал alex, это означает RETURN.
В сборке x86, когда компилятор достигает этой строки (например, в конце подпрограммы), она выталкивает значение last из стека, которое должно быть возвращающим адресом, и назначает его к регистру ИС. Это можно понять, написав простой код ассемблера и скомпилировав его с помощью Turbo Debugger. Там графический интерфейс для ассемблера, если вы новичок в этом. Здесь вы можете найти графический интерфейс .
Когда вы вставляете и выталкиваете значения из и в стек, когда находитесь в подпрограмме, вы должны сохранить возвращаемый адрес, потому что в конце подпрограммы вам нужно вставить его обратно в стек до return
.
Удачи!
Ответ 4
Это означает, что RETurn, например, return
на языках высокого уровня.
На большинстве машин он выдает предыдущее значение счетчика программы перед тем, как ввести подпрограмму в стек и скопировать ее в регистр ПК.
Для x86 аргумент представляет собой количество параметров в стеке. Это применимо только в том случае, если в используемом соглашении используется подпрограмма для сброса стека.
Ответ 5
Кажется, вы спрашиваете о ближайшем возврате с операндом для x86_64. Алгоритм, который сопровождается аппаратным обеспечением, когда рядом с RET встречается процессор, показан в Справочное руководство по набору инструкций Intel:
(* Near return *)
IF instruction = near return
THEN;
IF OperandSize = 32
THEN
IF top 4 bytes of stack not within stack limits
THEN #SS(0); FI; //throw protected mode exception
EIP ← Pop();
ELSE
IF OperandSize = 64
THEN
IF top 8 bytes of stack not within stack limits
THEN #SS(0); FI; //throw protected mode exception
RIP ← Pop();
ELSE (* OperandSize = 16 *)
IF top 2 bytes of stack not within stack limits
THEN #SS(0); FI; //throw protected mode exception
tempEIP ← Pop();
tempEIP ← tempEIP AND 0000FFFFH;
IF tempEIP not within code segment limits
THEN #GP(0); FI; //throw protected mode exception
EIP ← tempEIP;
FI;
FI;
IF instruction has immediate operand
THEN (* Release parameters from stack *)
IF StackAddressSize = 32
THEN
ESP ← ESP + SRC;
ELSE
IF StackAddressSize = 64
THEN
RSP ← RSP + SRC;
ELSE (* StackAddressSize = 16 *)
SP ← SP + SRC;
FI;
FI;
FI;
FI;
-
В соответствии с этим алгоритмом, когда встречается почти возврат, адрес возврата проверяется, находится ли он в пределах SS. Вершина стека выставляется в RIP или EIP в соответствии с размером операнда, если адрес возврата действителен.
-
Если размер операнда равен 16 битам, временное местоположение удерживает возвращенный адрес возврата, который имеет значение AND, со значением 0x0000FFFF и загружается в EIP после проверки пределов CS.
-
Как ваш вопрос задает вопрос о том, что произойдет, если есть операнд для кода операции ближней команды RET. Это зависит от размера адреса стека. В соответствии с этим размером RSP ESP или SP увеличивается на операнд, и после того, как все инструкции RET завершены, выполняются на аппаратном обеспечении.