┌──────────────────────────────┐ │ │ │ ФОРУМ │ │ │ └──────────────────────────────┘ (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 секун- ды до следующего прерывания. * * *