2

Я прочитал (и изучил) информацию об обработке прерываний.
Что я всегда не понимаю, откуда мы знаем, куда вернуться (PC/IP) из обработчика прерываний.
Как я понимаю:Где вернуться с прерывания

  1. на прерывание вызвано устройством (скажем, клавиатуру)
  2. Соответствующий обработчик вызывается - при запущенном процессе. То есть, никакой контекст не переключается на ОС.
  3. Обработчик прерываний завершает работу и передает управление обратно в запущенное приложение.

Процесс, изображенный выше, который является моим пониманием обработки прерываний, имеет место в контексте текущего текущего процесса. Таким образом, это похоже на вызов метода, а не на контекстный переключатель.
Однако, поскольку мы фактически не делали CALL для обработчика прерываний, у нас не было возможности вставить текущий IP-адрес в стек.
Итак, как мы узнаем, куда отскакивать от прерывания. Я смущен.

Порадовал бы любые объяснения, в том числе однострочные, которые просто указывают на хороший pdf/ppt, рассматривающий этот вопрос конкретно.
[Я обычно ссылаюсь на описанный выше процесс под Linux и кодом C, но приветствуются все хорошие ответы)

+0

Немного педантичный, но точка (2) выше не совсем так сказать. При прерывании ядро ​​определенно переключает «на ОС» в код ядра ring 0. Ядро может обслуживать прерывание без изменения указателя таблицы страниц CR3, поэтому в этом смысле нет контекстного переключателя. По этой причине пользователь обрабатывает все карты глобальных таблиц страниц ядра. – srking

+0

@srking: я буду педантичным заново - ясно, что обработчик зарегистрирован в ОС. Также в любом нормальном сценарии сам обработчик будет находиться в адресном пространстве ядра. Тем не менее, текущий процесс будет продолжаться - так что yup, без контекстного переключателя. Более того, любые отработанные циклы ЦП будут учитываться при учете этого процесса. – Trevor

ответ

1

Когда прерывание запускается, ЦПУ подталкивает несколько стеков в стек, включая указатель инструкции (EIP) кода, который выполнялся перед прерыванием. Вы можете поместить iret и конец вашего ISR, чтобы вывести эти значения, и восстановить EIP (а также CS, EFLAGS, SS и ESP).

Кстати, прерывания не обязательно запускаются устройствами. В Linux и DOS программы пользовательского пространства используют прерывания (через int) для выполнения системных вызовов. В некотором коде ядра используются прерывания, например, намеренно тройная ошибка, чтобы принудительно завершить работу.

+1

На Intel, да. Однако не в любой другой архитектуре. –

0

Механизм триггера прерывания в CPU толкает адрес возврата в стек (между прочим).

+0

Ну, это довольно системная зависимость. –

2

Это довольно зависимая архитектура.

На процессорах Intel адрес возврата прерывания помещается в стек при возникновении прерывания. Вы должны использовать команду iret для возврата из контекста прерывания.

На ARM, прерывание вызывает изменение режима процессора (в режим INT, FIQ или SVC, например), сохранение текущего CPSR (текущий регистр состояния программы) в SPSR (сохранено регистр состояния программы), поставив текущий адрес выполнения в LR нового режима (реестр ссылок), а затем переход к соответствующему вектору прерывания. Поэтому, возвращаясь из прерывания выполняется путем перемещения SPSR в CPSR, а затем прыгает на адрес сохраненной в LR - обычно делается в один шаг с subs или movs инструкции:

movs pc, lr 
Смежные вопросы