Часто процедурам требуются локальные переменные, которые не будут нужны после того, как процедура закончится. По аналогии с методами передачи параметров можно говорить о локальных переменных в регистрах — каждый регистр, который сохраняют при входе в процедуру и восстанавливают при выходе, фактически играет роль локальной переменной. Единственный недостаток регистров в роли локальных переменных — их слишком мало. Следующий вариант — хранение локальных данных в переменной в сегменте данных — удобен и быстр для большинства несложных ассемблерных программ, но процедуру, использующую этот метод, нельзя вызывать рекурсивно: такая переменная на самом деле является глобальной и находится в одном и том же месте в памяти для каждого вызова процедуры. Третий и наиболее распространенный способ хранения локальных переменных в процедуре — стек. Принято располагать локальные переменные в стеке сразу после сохраненного значения регистра ВР, так что на них можно ссылаться изнутри процедуры, как [ВР-2], [ВР-4], [ВР-б] и т.д.:
foobar proc near foobar_x equ [bp+8] ; параметры foobar_y equ [bp+6] foobar_z equ [bp+4] foobar_l equ [bp-2] ; локальные переменные foobar_m equ [bp-4] foobar_n equ [bp-6]
push bp ; сохранить предыдущий ВР mov bp,sp ; установить ВР для этой процедуры sub sp,6 ; зарезервировать 6 байт для ; локальных переменных (тело процедуры) mov sp,bp ; восстановить SP, выбросив ; из стека все локальные переменные pop bp ; восстановить ВР вызвавшей процедуры ret 6 ; вернуться, удалив параметры из стека foobar endp
Внутри процедуры foobar стек будет заполнен следующим образом (см. рис. 16).
Рис. 16. Стек при вызове процедуры foobar
Последовательности команд, используемые в начале и в конце таких процедур, оказались настолько часто применяемыми, что в процессоре 80186 были введены специальные команды ENTER и LEAVE, выполняющие эти же самые действия:
foobar proc near foobar_x equ [bp+8] ; параметры foobar_y equ [bp+6] foobar_z equ [bp+4] foobar_l equ [bp-2] ; локальные foobar_m equ [bp-4] ; переменные foobar_n equ [bp-6]
enter 6,0 ; push bp ; mov bp,sp ; sub sp,6 (тело процедуры) leave ; mov sp,bp ; pop bp ret 6 ; вернуться, ; удалив параметры ; из стека foobar endp
Область в стеке, отводимая для локальных переменных вместе с активационной записью, называется стековым кадром.