Ассемблер Это просто! Учимся программировать


ГЛАВА 06 - часть 3


/p>


Оператор Перевод Применение Процессор
STI reSTore Interrupt - восстановить Разрешить прерывания 8086

Для чего это нужно? Давайте рассмотрим это в двух словах, т.к. механизму работы прерываний необходимо посвятить целый выпуск. Если что-то не понятно - просто опустите, не обращайте внимания

Когда вы создали программу и запустили ее на выполнение, то работает не только она одна. Простейший пример - таймер, который вызывается примерно 18 раз в секунду для обновления. Компьютер всегда что-то делает! Даже тогда, когда ждет от вас нажатия клавиши. Что происходит, когда вызывается прерывание от таймера? Примерно тоже, что и при вызове процедуры. Компьютер запоминает в стеке адрес текущей команды, а также все регистры и переходит на адрес прерывания, по которому находится процедура обработки этого прерывания (например, таймера, которая обновит показания часов/минут/секунд). Затем, как процедура отработала, компьютер восстановит из стека адрес возврата и все регистры, и наша программа пойдет работать дальше

Вот пример, в котором мы изменим регистры SS:SP, не запрещая прерывания: (1) mov ax,100h (2) mov ss,ax (3) mov sp,200h

Допустим, прерывание таймера сработало после строки (2). Что у нас получилось? SS равен 100h, а SP еще не успел измениться. Получается, что сегмент стека верный, а смещение - осталось прежним (допустим, SP=0FFFEh). В итоге, SS=100h, а SP=0FFFEh. Компьюетр и сохранит по этому адресу данные. Какой при этом код программы затрется - не известно. Мы ведь хотели сделать SS=100h, а SP=200h! Хорошо, если две строки успели выполниться перед вызовом прерывания. Хорошо также, если по адресу 100h:0FFFEh ничего нет (память свободна). А если есть? Тогда компьютер, скорее всего, "зависнет".

Отсюда два правила:

1) Прежде чем менять регистры SS:SP, необходимо запретить все прерывания командой cli, а затем разрешить командой sti.

2) SS:SP нужно устанавливать на свободную область памяти. При этом следует убедиться, что код не утратил работоспособности.

Мы знаем, что после загрузки com-программы в память, SS равен сегменту, куда загрузилась программа, а SP - 0FFFEh. Код программы начинается с адреса 100h (org 100h). Вершина стека - конец нашего сегмента. Если наша программа занимает, скажем 2000h байт, то можем установить SP в 2200h. В этом случае мы отводим 100h (именно сто) байт для стека (т.к. программа загружается по адресу 100h, то 2000h нужно прибавить 100h). Стек, как вы помните, растет снизу вверх. Если мы переполним стек (например, поместим более 100h данных), то затрется часть нашей программы снизу. Имейте это ввиду!

Вот пример изменеия регистров стека: cli mov ax,0B900h mov ss,ax mov sp,100h sti




Начало  Назад  Вперед