CodeNet / Платформы / Пишем ОС / Пишем "многозадачную" ОС в "Real Mode"
Выгружаем задачу
Сначала о том, как заканчиваются COM-программы MS-DOS:
int 20h
Метод перехвата: тут понадобится перехватить прерывание int 20h, из которго управление будет передаватся на процедуру выгрузки задачи.
mov ah,4Ch int 21h
Метод перехвата: В конце концов, из 21-го прерывания вызывается 20h, то есть см. int 20h
ret
Метод перехвата: Все просто, при загрузке задачи, стек находится по адресу SS:FFFE, то есть при корректном окончании задачи стек находится там-же, и инструкция ret передает управление на адрес указанный в SS:FFFF. Именно туда мы записываем значение '0' и следовательно управление передается на адрес CS:0000, а там мы тихо мирно, расплогаем инструкцию int 20h то есть см. выше.
Обрабочик прерывания 20h
PROC newint20 ; Прерывание 020h (выгрузка задачи) call _di
Запрещаем прерывания, что-бы задача не включилась в момент ее выгрузки.
pop ax ;¬ pop ax ;¦ Достаем всякое дерьмо из стека pop ax ;+
Достаем из стека, то что там осталось после команды int 20h (CS,IP и флаги - они теперь нам больше не нужны).
push cs pop ds lea di,[cs:firsttask] ; DI = Адрес начала структуры TTASK mov al,[cs:numtask] ; AL = Номер задачи xor ah,ah ; AX = Номер задачи push dx mov dx,515 mul dx ; AX = Смещения от начала firsttask pop dx add di,ax ; DI = Абсолютное смещение вершины ; стека в структуре TTASK
Узнаем номер текущей задачи, и записываем в ее id значение 255 - то есть задача не загружена.
mov [Byte Ptr cs:di],255 mov dx,[cs:di+3] call FreeMemory call _ei jmp int08new
Освобождаем память, включаем обратно прерывания и переходим к выполнению восьмого прерывания - переключения задач, там и прозойдет включение следующей задачи.
ENDP newint20