Enter
создает кадр стека, а leave
уничтожает кадр стека. С параметрами 0,0
на enter
они в основном эквивалентны:
; enter
push ebp
mov ebp, esp
; leave
mov esp, ebp
pop ebp
Хотя он не используется в опубликованном вами коде, enter
поддерживает выполнение немного большего, чем простая комбинация push/mov, показанная выше. Первый параметр enter
указывает количество места, выделяемого для локальных переменных. Например, enter 5, 0
примерно эквивалентно:
push ebp
mov ebp, esp
sub esp, 5
Enter
также поддерживает такие языки, как Pascal, которые могут использовать вложенные функции/процедуры:
procedure X;
procedure Y;
begin
{ ... }
end
begin
{ ... }
end
В таком случае Y
имеет доступ не только к своим локальным переменным, но и ко всем локальным переменным X
. Они могут быть вложены до произвольной глубины, поэтому вы можете иметь Z
внутри Y
, который имеет доступ к своим собственным локальным переменным, а также к переменным Y
и переменным X
. Второй параметр enter
указывает глубину вложенности, поэтому X
будет использовать enter Sx, 0
, Y
будет использовать enter Sy, 1
, а Z
будет использовать enter Sz, 2
(где Sx
, Sy
и Sz
означают размер переменных, локальных для X
, Y
и Z
соответственно).
Это создаст цепочку кадров стека, чтобы предоставить Z
доступ к переменным, локальным для Y
и X
, и так далее. Это становится довольно нетривиальным, если функции рекурсивны, поэтому вызов Z
не может просто пройти вверх по стеку до двух самых последних кадров стека - ему нужно пропустить кадры стека от предыдущих вызовов самого себя и перейти непосредственно вернуться к кадрам стека для лексической родительской функции/процедуры, которая отличается от вызывающей в случае рекурсии.
Эта сложность также является причиной того, что C и C++ запрещают вложенные функции. Учитывая наличие ввода/вывода, их довольно легко поддерживать на процессорах Intel, но может быть значительно сложнее на многих других процессорах, в которых такая прямая поддержка отсутствует.
Это также, по крайней мере, помогает объяснить еще одну... особенность enter
- для используемого здесь тривиального случая (например, enter 0, 0
) это немного медленнее, чем эквивалент с использованием push
/mov
.
person
Jerry Coffin
schedule
02.05.2011
EBP
Неверно, он сохраняет длину вebx
- person ecm   schedule 09.03.2021