5.2.2. Локальные переменные

Часто процедурам требуются локальные переменные, которые не будут нуж­ны после того, как процедура закончится. По аналогии с методами передачи пара­метров можно говорить о локальных переменных в регистрах - каждый регистр, который сохраняют при входе в процедуру и восстанавливают при выходе, фактически играет роль локальной переменной. Единственный недостаток реги­стров в роли локальных переменных - их слишком мало. Следующий вариант -хранение локальных данных в переменной в сегменте данных - удобен и быстр для большинства несложных ассемблерных программ, но процедуру, использую­щую этот метод, нельзя вызывать рекурсивно: такая переменная на самом деле яв­ляется глобальной и находится в одном и том же месте в памяти для каждого вызова процедуры. Третий и наиболее распространенный способ хранения ло­кальных переменных в процедуре - стек. Принято располагать локальные пере­менные в стеке сразу после сохраненного значения регистра так что на них можно ссылаться изнутри процедуры, как [ВР-2], [ВР-4], [ВР-6] и т.д.:

foobar

 

proc

near

foobar_x

 

equ

[bp+8]    ; Параметры.

foobar_y

 

equ

[bp+6]

foobar_z

 

equ

[bp+4]

foobar_l

 

equ

[bp-2]    ; Локальные переменные.

foobarjn

 

equ

[bp-4]

foobar_n

 

equ

[bp-6]

 

push

bp

; Сохранить предыдущий ВР.

 

mov

bp, sp

Установить BP для этой процедуры.

 

sub

sp,6

Зарезервировать 6 байт для

 

 

 

; локальных переменных.

 

(тело

процедуры)

 

 

mov

sp, bp

;  Восстановить SP, выбросив

 

 

 

;  из стека все локальные переменные.

 

pop

bp

;  Восстановить ВР вызвавшей процедуры.

 

ret

6

;  Вернуться, удалив параметры из стека.

foobar

 

endp

 

Внутри процедуры foobar стек будет заполнен так, как показано на рис. 16.

Последовательности команд, используемые в начале и в конце названных проце­дур, оказались настолько часто применяемыми, что в процессоре были введе­ны специальные команды ENTER и LEAVE, выполняющие эти же самые действия:

foobar proc near

foobar_x equ      [bp+8]   ; Параметры.

foobar_y equ [bp+6]

foobar_z foobar_l foobar_m

n

equ equ equ equ

enter 6,0

(тело процедуры) leave

ret

foobar

6

endp

[bp+4] [bp-2] [bp-4] [bp-6]

Локальные переменные.

push bp mov bp.sp sub sp,6

mov sp.bp

pop bp

Вернуться, удалив , параметры из стека.

Область в стеке, отводимая для локальных перемен­ных вместе с активизационной записью, называется сте­ковым кадром.

IP

BP

м

N

BP

SP

Рис. 16. Стек при вызове процедуры foobar