┌──────────────────────────────┐
│ │
│ ФОРУМ │
│ │
└──────────────────────────────┘
(c) Иван Рощин, г.Москва, 1997
По поводу релоцируемых программ
Прочитав несколько статей в
ZX-РЕВЮ, посвященных релоцируе-
мым программам, я заметил, что
для определения базового адреса
обычно используется следующий
способ:
140.
CALL #007C ; По этому адресу - RET.
DEC SP ; Т.к. в стеке находится
DEC SP ; адрес возврата.
POP HL ; Снимаем адрес со стека.
2
У этого способа есть несколь-
ко недостатков:
- если во время работы этого
фрагмента программы произойдет
прерывание, содержимое стека бу-
дет испорчено, и в результате
получим неверный адрес. Поэтому
приходится запоминать состояние
триггера прерываний, запрещать
прерывания, а потом восстанавли-
вать прежний режим их работы.
Все это приводит к дополнитель-
ным затратам памяти.
- способ не сработает, если
по адресу #007C нет команды RET
(нестандартное ПЗУ).
- большая длина фрагмента (6
байт).
Есть способ, свободный от
указанных выше недостатков:
HALT ; В стек запишется адрес
; следующей команды (для
; возврата из прерывания)
DEC SP ; Так же, как и в первом
DEC SP ; фрагменте,
POP HL ; снимаем адрес со стека
При этом расход памяти соста-
вит лишь четыре байта вместо
шести. В отличие от предыдущего
примера, прерывания во время ра-
боты этого фрагмента программы
должны быть разрешены (чтобы вы-
полнилась команда HALT). Несмот-
ря на это, между командами DEC
SP прерывание не может произой-
ти, т.к. после выполнения коман-
ды HALT остается еще 1/50 секун-
ды до следующего прерывания.
* * *