Assembler - язык неограниченных возможностей

         

Вложенные процедуры с дисплеями


Вместо того чтобы передавать адрес только одной вышестоящей активационной записи, процедурам можно передавать набор адресов сразу для всех уровней вложенности — от нулевого до непосредственно вышестоящего. При этом доступ к любой нелокальной процедуре сводится всего к двум командам, а перед вызовом процедуры вообще не требуется каких-либо дополнительных действий (так как вызываемая процедура поддерживает дисплей самостоятельно).

proc_at_3 proc near push bp ; сохранить динамическую ссылку mov bp,sp ; установить адрес текущей записи push display[6] ; сохранить предыдущее ; значение адреса третьего ; уровня в дисплее mov display[6],bp ; инициализировать третий ; уровень в дисплее sub sp,N ; выделить место для ; локальных переменных [...] mov bx,display[4] ; получить адрес записи для уровня 2 mov ax,ss:[bx-6] ; считать значение второй ; переменной из уровня 2 [...] add sp,N ; освободить стек от ; локальных перееденных pop display[6] ; восстановить старое ; значение третьего уровня в дисплее pop bp ret proc_at_3 endp

Здесь считается, что в сегменте данных определен массив слов Display, содержащий адреса последних использованных активационных записей для каждого уровня вложенности: display[0] содержит адрес активационной записи нулевого уровня, display[2] — первого уровня и так далее (для близких адресов).

Команды ENTER и LEAVE можно использовать для организации вложенности с дисплеями, но в этой реализации дисплей располагается не в сегменте данных, а в стеке, и при вызове каждой процедуры создается его локальная копия.

; enter N,4 (уровень вложенности 4, N байт на стековый кадр) ; эквивалентно набору команд push bp ; адрес записи третьего уровня push [bp-2] push [bp-4] push [bp-6] push [bp-8] ; скопировать дисплей mov bp,sp add bp,8 ; BP = адрес начала дисплея текущей записи sub sp,N ; выделить кадр для локальных переменных

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



Содержание раздела