Переключение стека в резидентной программе. 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Переключение стека в резидентной программе.



 

При реализации процедуры прерывания (аппаратного или программного) процессор сохраняет в стеке прерванной задачи регистр флагов, сегментный регистр, регистр команд cs и указатель команд ip и загружает из вектора прерывания в регистры cs и ip двухсловный адрес обработчика прерывания. Все остальные регистры хранят эту информацию, которая в них была на момент прерывания. Для того, чтобы не разрушать прерванную задачу, в самом начале обработчика прерывания следует сохранить все используемые в обработчике регистры, а перед командой iret - восстановить их. Это относится к сегментным регистрам и к РОН. Все команды обращения к памяти используют по умолчанию в качестве сегментного регистра - регистр ds. Если при переходе в обработчик не выполнить настройку ds на сегмент обработчика, то команды вида:

mov ax, mem

mov bx,[si]

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

mov ax,cs:mem

mov bx,cs:[si]

Особая ситуация возникает со стеком. При переходе в обработчик регистры ss и sp настроены на стек прерванной задачи. Если этот стек имеет достаточный объем, то обработчик его может использовать, а если нет - переполнение стека может привести к разрушению прерванной программы. Поэтому надежнее в обработчике прерывания иметь собственный стек. Если TSR программа «паразитирует» на чужом стеке, то в этом случае использование стека должно быть минимальным.

Смена стека требует запоминания кадра стека (содержимого ss и sp) в ячейках памяти отведенной обработчику, занесения в ss и sp новых значений и восстановления старого кадра перед выходом и обработчика. Естественно, что для стека должен быть выделен свободный объем (необходимый для запоминания своих данных, а может быть и чужих, от программ, «паразитирующих» на чужом стеке).

Если резидентная программа не допускает повторной активизации в процессе своей заботы, то можно не делать проверку переключения стека, и смена стека может быть осуществлена следующим образом:

org 100

start: jmp begin

ss_seg dw 0

ss_offs dw 0

mem dw 0

.

.

new_handler proc far

mov cs:ss_seg,ss;сохранение кадра стека прерванной задачи

mov cs:ss_offs,sp

cli;запрет прерываний

mov cs:mem,cs;настроим ss на наш сегмент

mov ss,cs:mem

mov sp,offset end_res;настроим sp

sti;разрешим прерывания

; теперь работаем на стеке резидентной программы

.

.

.

;в конце резидентной части:

stack_area dw 256 dup (?)

new_handler endp

end_res=$

Процедура обработчика прерывания начинается с сохранения кадра стека прерванной задачи. Адресация ячеек выполняется через cs, поскольку ds еще указывает на сегмент данных вызвавшей программы. Установка нового кадра стека всегда выполняется при запрещенных прерываниях, т.к. если аппаратное прерывание произойдет между командами заполнения ss и sp, вектор прерванного процесса будет сохранен в случайной ячейки памяти. Заполнить сегментный стека можно и так:

push cs

pop ss

Однако это выполняется на стеке прерванной программы, приведенный же пример не затрагивает ни стека прерванной задачи, ни регистр ax, ни других регистров. Т.к. команда mov ss, cs запрещен, то содержимое cs копируется в ss через ячейку памяти mem. Команда mov sp, offset end_res заносит адрес для первого стека, место под которым выделено в самом конце резидентной чести обработчика. Под стек отведено 256 слов.

При запуске программы на выполнение DOS находит свободную область памяти подходящего размера. В начале программы создается префикс программного сегмента (PSP) размером в 256 байт. Сама программа загружается вслед за PSP. Кроме того, DOS передает программе копию среды. Размер среды от 160 байт для MS DOS 3.3 и выше. Сегментный адрес среды помещается в PSP по смещению 2ch. Резидентные программы практически никогда не используют среду DOS, занимаемую ею память можно освободить с помощью функции 49h.

mov es, word ptr ds:[2ch];загрузить сегментный адрес среды в es

mov ah, 49h;и освободить память

int 21h

Резидентная программа не нуждается и в PSP. Младшая часть PSP (до смещения 5ch) используется DOS и в последний раз потребуется при выполнении функции 31h или прерывания 27h. В дальнейшем DOS будет использовать PSP прерванной программы.

Некоторые TSR программы используют PSP программы, например, пересылают резидентную часть программы в PSP c помощью команды movsb, уменьшая тем самым размер резидентной позиции. Однако, надежнее, проще и целесообразнее найти применение PSP в резидентной программе. Например, использовав его как буфер ввод-вывод или разместив в нем собственный стек. Последнее выполняется следующим образом:

вместо mov SP, offset end-res

mov SP, offset start

При этом получаем стек глубиной 256 бит или 128 слов, т.е. все PSP.

 



Поделиться:


Последнее изменение этой страницы: 2017-02-07; просмотров: 288; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.129.210.17 (0.004 с.)