Тип
>>> import this
в консоли Python.
, Хотя это обычно рассматривают как (прекрасный!) шутка, это содержит несколько допустимых определенных для Python аксиом.
В мнемонике ret N, N - размер параметров в стеке. В данном случае это 4 * 4 = 16 (10h) для 4 DWORD.
Но это относится только к соглашениям о вызовах, когда вызываемый объект отвечает за очистку стека. В случае соглашения cdecl, ret должен быть без цифр, так как вызывающий отвечает за очистку стека.
На самом деле существует только два разных возврата, retn ( ближний возврат) и retf (дальний возврат). Когда вы просто используете ret, ассемблер или компилятор достаточно умен, чтобы выбрать, какой из них вам нужен. Ближайший возврат - это переход к существующему сегменту кода, дальний возврат - это переход к другому сегменту кода. В Windows у вас есть только один сегмент кода, и поэтому ret должен быть просто мнемоникой для retn. Отдельные инструкции retn и retf - это возврат к прежним временам, когда модели сегментированной памяти были обычным явлением. Практически все 32-разрядные системы x86, работающие сегодня, используют плоскую, не сегментированную модель памяти.
Ret без аргумента выталкивает адрес возврата из стека и переходит к нему. Некоторые соглашения о вызовах (например, __stdcall) указывают, что вызываемая функция очищает стек. В этом случае они вызывают ret с количеством байтов, чтобы удалить эти параметры из стека. 16 байтов - это параметры функции winmain.
На самом деле это два типа: retn
и retf
. Третий ret
кодируется ассемблером в один из первых двух.
Разница в том, что retn
(return near) вытолкнет только указатель инструкции (IP). В то время как retf
(return far) вытолкнет указатель инструкции (IP) и сегмент кода (CS).