maisvendoo писал(а):
Значит при создании новой задачи:
1. Заполняем её описатель
2. Ставим в очередь.
3. Формируем вручную стек - помещаем туда все необходимые значения, ESP ставим указывающим на вершину стека.
4. Делаем call на задачу, при этом адрес возврата помещается в стек новой задачи
Нет.
1. Заполняем кадр возобновления (размещаемый под вершиной стека задачи) и структуру задачи (они у меня располагаются последовательно, т.е. стек находится прямо под структурой задачи).
2. Ставим в очередь.
3. Делаем "call SwitchToNext" или просто продолжаем заниматься своими делами, пока переключение не произойдет само (по таймеру или как-то еще).
Цитата:
При переключении:
1. Запоминаем ESP текущей задачи
2. Берем следующую задачу из очереди
3. Помещаем в регистр ESP его значение для следующей задачи
Да. Только я это делал внутри подпрограммы переключения. И не забываем обновить current.
Цитата:
Таким образом у нас меняется стек, при завершении обработчика управление передается по адресу сохраненному в стеке при создании задачи. Я правильно понял?
Т.к. я делал переключение в отдельной подпрограмме, то у меня переключение происходило не при завершении обработчика, а внутри обработчика. Например, представь, что переключение на новую задачу происходит по таймеру, тогда содержимое стека прерванной задачи будет таким:
Код:
XXXX - содержимое стека на момент возникновения прерывания
EFLAGS
CS
EIP
XXXX - результат работы pusha
DS
ES
RRRR - адрес возобновления прерванной задачи (результат работы call SwitchToNext)
FS
GS
EFLAGS
В стеке новой задачи находится только кадр возобновления:
Код:
SSSS - стартовый адрес новой задачи
FS=0
GS=0
EFLAGS для новой задачи
Как видно, код обработчика, вызвавшего переключение на новую задачу, еще не завершился. Он будет завершен только тогда, когда управление будет возвращено прерванной задаче.