Использование средств 32-разрядных процессоров в программировании
Как уже отмечалось, при разработке 16-разрядных программ реального режима, предназначенных для выполнения по управлением операционной системы MS-DOS, вполне допустимо использование ряда дополнительных возможностей 32-разрядных процессоров. В реальном режиме можно использовать:
- 32-разрядные операнды;
- дополнительные команды и расширенные возможности команд МП 86;
- дополнительные режимы адресации;
- четыре сегментных регистра для адресации данных вместо двух.
Для того, чтобы транслятор распознавал все эти средства, необходимо начать программу с директивы 0.586 (или, при желании, 0.486 или 0.386) и указать при этом для сегментов команд и данных описатель use 16, чтобы программа осталась 16-разрядной.
Следует заметить, что возможности использования в программах реального режима дополнительных средств 32-разрядных процессоров, хотя и кажутся привлекательными, в действительности весьма ограничены. Новых команд не так уж много, и они не имеют принципиального характера; 32-разрядные данные используются в прикладных программах относительно редко (если не касаться вычислительных программ, содержащих действительные числа, но такие программы редко пишут на языке ассемблера); расширенные возможности адресации в полной мере проявляются лишь в 32-разрядных программах, не работающих в DOS. Тем не менее в каких-то случаях привлечение средств 32-разрядных процессоров может оказаться полезным и в 16-разрядных программах, и мы приведем несколько примеров их использования.
Среди системных данных DOS и BIOS есть данные, требующие для своего размещения 2 слов. К таким данным, в частности, относится системное время, накапливаемое в 4х-байтовой ячейке с абсолютным адресом 46Ch. Выше, в разделе 3.5, уже описывалась системная процедура отсчета текущего времени. В процессе начальной загрузки компьютера в ячейку с адресом 46Ch переносится из часов реального времени время, истекшее от начала суток, а затем содержимое этой ячейки увеличивается на 1 каждым прерыванием от системного таймера, подключенного к вектору 8. Чтение ячейки 46Ch позволяет определить текущее время с погрешностью приблизительно в 1/18 секунды, что позволяет достаточно точно измерять интервалы времени. Арифметические действия с системным временем удобно выполнять в расширенных 32-разрядных регистрах.
Рассмотрим программу, которая позволяет установить требуемый временной интервал и отработать некоторым образом его окончание. Поскольку MS-DOS является однозадачной системой, единственным способом организации параллельных процессов – выполнения программы и ожидания окончания временного интервала – является использование механизма прерываний. В нашем случае программа содержит обработчик прерываний от системного таймера, который 18 раз в секунду читает системное время и сравнивает его значение с заданной заранее величиной. При достижении равенства обработчик прерываний либо сам отрабатывает это событие, либо устанавливает флаг окончания временного интервала, который периодически тестируется в основной программе. Первый вариант позволяет измерить временной интервал с большей точностью, но второй предоставляет больше возможностей, так как в обработчике прерываний нельзя обращаться к функциям DOS, а основная программа может делать все, что ей заблагорассудится.
Приведенный ниже пример выполнен в виде программы типа.СОМ. Такая организация программы упрощает обработчик прерываний и облегчает его написание. Дело заключается в том, что процессор, переходя по аппаратному прерыванию на обработчик прерывания, модифицирует только регистры CS:IP (значениями, полученными из вектора прерываний). Все остальные регистры, в том числе и сегментные, сохраняют те значения, которые они имели на момент прерывания. Значения эти могут быть какими угодно, особенно, если основная программа вызывает функции DOS.
Поэтому, если в обработчике прерываний необходимо обратиться к данным, хранящимся в основной программе, нам необходимо настроить какой-либо из сегментных регистров (например, DS или ES) на сегментный адрес сегмента данных основной программы. Если же программа написана в формате.СОМ, то ее поля данных входят в тот же (единственный) сегмент, где расположены команды, и для обращения к данным можно воспользоваться регистром CS, который при вызове обработчика настраивается процессором.