Фантазии о Вселенной и мой личный сайт
2.7 Заглушки

2.7 Заглушки

Заглушками называются процедуры, которые не допускают дальнейшее выполнение программы. При этом они либо явно зацикливают процессор (простая заглушка), либо производят возврат в режим реальных адресов и прекращение программы. На стадии разработки и отладки операционной системы защищённого режима заглушки являются нормальной частью программы.

При обработке простой заглушки процессор, естественно, "виснет", зато есть гарантия, что он остался в нужной точке программы, а не выполняет не предусмотренные действия. Пример такой заглушки - команда JMP с адресом перехода на саму себя, реализованный в примере 4 в предыдущей главе.

Однако, для нас всегда важно знать, откуда был переход на заглушку и причину этого перехода, поэтому в этой главе мы рассмотрим использование заглушек вместо обработчиков исключений, которые будут сообщать об исключении, переводить процессор в R-Mode и прекращать программу.

При вызове обработчика исключения процессор помещает в стек информацию, благодаря которой можно узнать причину возникшего исключения. Указателем на стек является пара регистров SS:SP, но т.к. мы рассматриваем программирование 32-разрядных процессоров, то во всех указателях будем использовать 32-разрядное смещение; для стека это будет SS:ESP. На рис. 7-1 представлен формат стека обработчика исключения после передачи ему управления:

Не все исключения снабжаются кодом ошибки, поэтому для каждого обработчика нужно учитывать его наличие (см. в Приложениях "Исключения и прерывания защищённого режима").

Для вывода информации об исключениях в примере к этой главе введены следующие процедуры:

  • put_zs - вывод ZS-строки (ZS = Zero-String - строка, заканчивающаяся нулём)
  • put_db_num, put_dw_num и put_dd_num - вывод db-, dw- и dd-числа соответственно.

Эти процедуры производят вывод на экран в координаты X,Y, переданные в регистре DX и с атрибутом цвета, определённым в переменной text_color. Для преобразования координат в адрес используется процедура "get_adr".

Далее, во всех наших примерах эти процедуры сохранятся и для текстового режима на них будет построена система вывода.

Процедура putzs, определённая в предыдущих примерах, остаётся. Она является универсальной, т.к. для вывода использует адрес видеопамяти в паре регистров ES:DI и может использоваться как в R-Mode, так и в P-Mode.

Исходный текст этих процедур здесь не приводится, т.к. целью данной главы является определение заглушек, а не вывод на экран. В конце главы есть ссылка на архив с исходником, где вы сможете посмотреть реализацию этих процедур.

Принцип работы заглушек для всех исключений у нас одинаков - вывести на экран надписи и значения, переданные в стеке, поэтому все эти действия будет выполнять одна процедура "stopper".

Stopper имеет два входных параметра:

  • номер исключения в регистре AL
  • значение флага CF в EFLAGS - если CF = 1, значит в стеке есть кода ошибки.

Все обработчики исключений теперь будут заменены на следующие последовательности команд:

  • Для исключений без кода ошибки (например, исключение деления на 00h):
    mov al, 00h     ; Номер исключения.
    clc             ; Кода ошибки нет.
    jmp stopper
    
  • Для исключений с кодом кода ошибки (например, исключение общей защиты 0Dh):
    mov al, 0dh  ; Номер исключения.
    stc          ; Код ошибки есть.
    jmp stopper
    

Для возврата в режим реальных адресов теперь используется переход на метку "Return_to_R_Mode".

Далее следует текст заглушки "stopper": исходный текст программы пропущен

Для демонстрации работы заглушек используется команда UD2, предназначенная для генерации исключения недопустимой команды.

Процедуры смотреть здесь.