Этот способ наиболее часто используется для передачи аргументов при вызове процедур. Вызывающая процедура самостоятельно заносит в стек передаваемые данные, после чего производит вызов вызываемой процедуры.
При передаче управления процедуре микропроцессор автоматически записывает в вершину стека адрес возврата в вызывающую программу. Если перед передачей управления процедуре командой call в стек были записаны переданные процедуре данные или указатели на них, то они окажутся под адресом возврата.
Стек обслуживается тремя регистрами: SS, ESP и EBP. Содержимое регистров SS и ESP изменять не рекомендуется, поскольку микропроцессор работает с регистрами SS и ESP в предположении, что они всегда указывают на вершину стека.
Для осуществления произвольного доступа к данным в стеке архитектура микропроцессора имеет специальный регистр EBP (Base Point – указатель базы). Так же как и для регистра ESP, использование EBP автоматически предполагает работу с сегментом стека. Перед использованием этого регистра для доступа к данным стека его содержимое необходимо правильно инициализировать, что предполагает формирование в нем адреса, который бы указывал непосредственно на переданные данные. Для этого в начало процедуры включается дополнительный фрагмент кода, который называется прологом процедуры:
//пролог
push EBP // сохраняет содержимое EBР в стеке с тем, чтобы //исключить порчу находящегося в нем значения в вызываемой //процедуре
mov EBP,ESP //настраивает EBP на вершину стека
Аргументы процедуры находятся в стеке, начиная с адреса [EBP+8] – для 32 разрядной адресации для far -процедур.
Конец процедуры (эпилог) также должен быть оформлен особым образом и содержать действия, обеспечивающие корректный возврат из процедуры.
Эпилог процедуры – фрагмент кода, который восстанавливает контекст программы в точке вызова вызываемой процедуры из вызывающей программы.
Необходимо откорректировать содержимое стека, убрав из него ставшие ненужными аргументы, передававшиеся в процедуру. Это можно сделать следующими способами:
· использовать последовательность из п команд POP xx, лучше всего это делать в вызывающей программе сразу после возврата управления из процедуры;
· откорректировать регистр указателя стека ESP на величину k*п, например, командой ADD ESP, NN, где NN=k*n, и п – количество аргументов,
k -длина аргумента в байтах. Это также лучше делать после возврата управления вызывающей процедуре;
· используя машинную команду RET n в качестве последней исполняемой команды в процедуре, где п – количество байт, на которое нужно увеличить содержимое регистра ESP после того, как со стека будут сняты составляющие адреса возврата. Этот способ аналогичен предыдущему, но выполняется автоматически микропроцессором.
Например:
//эпилог
pop EBP // извлекает содержимое EBР из стека
ret //возврат из подпрограммы