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

Локальные переменные в Assembler используются для хранения промежуточных результатов во время выполнения процедуры. В отличие от глобальных, эти переменные являются временными и создаются при запуске процедуры.

Для локальных переменных существует понятие области видимости — так называется область программы, в которой доступна переменная. Обычно в ассемблере область видимости ограничена процедурой, создавшей локальную переменную.

Создание локальных переменных

Чтобы создать локальные переменные в процедуре, необходимо выделить для них память. Нужно вычесть из регистра SP значение, равное суммарному размеру всех локальных переменных в процедуре. Так как ширина стека равна 16 бит, то это значение должно быть кратно 2 байтам. При выходе из процедуры нужно восстановить указатель стека. Обычно это выполняется командой mov, sp, bp. Код процедуры с локальными переменными будет выглядеть так:

;Процедура с локальными переменными
myproc:
    push bp                 ;Сохранение BP
    mov bp,sp               ;Копирование указателя стека в BP
    sub sp,locals_size      ;Выделение памяти для локальных переменных
    ...
    mov sp,bp               ;Восстановление указателя стека
    pop bp                  ;Восстановление BP
    ret                     ;Возврат из процедуры

Код, выполняемый при входе в процедуру, называют также кодом пролога, а код, выполняемый при выходе, — кодом эпилога. Область стека, включающая в себя параметры процедуры, адрес возврата, локальные переменные и сохранённые регистры, называется кадром или фреймом стека.

Команды ENTER и LEAVE

В системе команд процессоров x86 существуют также специальные команды для работы с кадром стека процедуры: ENTER и LEAVE.

Команда ENTER обычно размещается в начале процедуры. У неё два непосредственных операнда: первый операнд — размер памяти, выделяемой под локальные переменные, второй операнд — уровень вложенности. В нашем примере второй операнд будет равен 0. Тогда по действию команда будет аналогична трём следующим командам:

    push bp                 ;\
    mov bp,sp               ; > или enter locals_size,0
    sub sp,locals_size      ;/

Второй операнд этой команды позволяет организовывать вложенные области видимости, как в некоторых языках высокого уровня. В ассемблере эти возможности используются редко.

Команда LEAVE не имеет операндов и аналогична по действию двум командам:

    mov sp,bp               ;\
    pop bp                  ;/ или leave

А так будет выглядеть наша процедура, если использовать команды ENTER и LEAVE:

;Пример процедуры с двумя локальными переменными
;вход: параметр x в стеке
;выход: AX = вычисленное значение
simpleproc2:
    enter 4,0               ;Создание кадра стека
 
    mov word[bp-4],1234     ;Инициализация первой локальной переменной
    mov byte[bp-2],10       ;Инициализация второй локальной переменной
 
    mov ax,[bp+4]           ;AX = x
    div byte[bp-2]          ;AL = x/10
    xor ah,ah               ;AX = x/10
    add ax,[bp-4]           ;AX = 1234+x/10
 
    leave                   ;Освобождение памяти, восстановление BP
    ret 2                   ;Возврат из процедуры

Сокращенный вариант:

;Процедура с локальными переменными
myproc:
    push bp                 ;Сохранение BP
    mov bp,sp               ;Копирование указателя стека в BP
    sub sp,locals_size      ;Выделение памяти для локальных переменных
    ...
    leave                   ;Освобождение памяти, восстановление BP
    ret                     ;Возврат из процедуры

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Загрузка...

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *