Доступ к памяти
В Турбо Паскале можно напрямую обращаться к ячейкам памяти, организованным в три типа предопределенных одномерных массивов и представляющих элементы различного формата:
Mem – Byte,
MemW – Word,
MemL – Longint.
Для доступа к элементам массивов используется специальный синтаксис, состоящий из номера сегмента и номера ячейки памяти, оба типа Word:
Mem[$0040:$0049]:=7;
Data := MemW[Seg(V):Ofs(V)];
Обращение к оперативной памяти по физическим адресам обычно используется для доступа к системной информации DOS и BIOS и разрешено только в однопользовательских операционных системах, например MS-DOS.
Доступ к портам ввода-вывода
В процессорах фирмы Intel используется изолированный ввод-вывод. То есть область адресов памяти отделена от области внешних устройств. Все подключаемые внешние устройства с точки зрения процессора выглядят одинаково и являются портами ввода-вывода.
Для доступа к этим портам используются два предопределенных массива
Port, PortW
соответственно с типами byte и word.
Когда элементу массива Port или PortW присваивается значение, это действие интерпретируется как вывод значения в порт.
Когда элемент массива выступает как операнд в выражении, то доступ к порту понимается как ввод с порта. Например:
{ Разрешение дальнейшей работы контроллера прерываний }
Port[$20]:=$20;
{ Установка в 1 заданных линий порта }
PortW[Base]:=PortW[Base] or Maska;
{ Ожидание установки в 0 старшей линии порта }
While (Port[$82] and $80)=0 do;
Пример доступа к порту клавиатуры для управления движением курсора.
Program Kyrsor;
{ Демонстрационный пример доступа к порту клавиатуры для управления движением курсора }
Uses Crt; { используется для создания задержки }
Var Mode, { записываемый в порт байт }
Ch:byte; { число, читаемое с клавиатуры }
Begin
Writeln(' Выберите режим ввода символов:');
Writeln(' Задержка перед первым повторением:');
Writeln(' 1 - 250 мс');
Writeln(' 2 - 500 мс');
Writeln(' 3 - 750 мс');
Writeln(' 4 - 1 с');
Repeat
Read(Ch);
Until Ch in [1..4];
Case Ch of
1: Mode:=0;
2: Mode:=$20;
3: Mode:=$40;
4: Mode:=$60;
end;
Writeln(' Частота перемещения, раз/сек:');
Writeln(' 1 - 30');
Writeln(' 2 - 20');
Writeln(' 3 - 10');
Writeln(' 4 - 5');
Writeln(' 5 - 2');
Repeat
Read(Ch);
Until Ch in [1..5];
Case Ch of
2: Mode:=Mode or 4;
3: Mode:=Mode or $0a;
4: Mode:=Mode or $14;
5: Mode:=Mode or $1f;
end;
{ Команда на установку режима }
Port[$60]:=$f3;
{ Задержка на восприятие }
Delay(10);
{ Код режима }
Port[$60]:=Mode;
end.
Работа по прерываниям
Программный интерфейс DOS и BIOS организован в виде обращения к процедурам по прерываниям.
Прерыванием является указание процессору на то, что произошло какое-либо событие и требуется его обработка, называемая реакцией на прерывание.
Прерывания делятся на внешние по отношению к процессору, например от часов реального времени, и внутренние, например деление на ноль или переполнение. Более того, любое прерывание можно вызвать командой
INT n
где n - номер прерывания, обычно обозначается в шестнадцатеричной системе счисления (с буквой Н в конце числа).
Реакцией процессора на прерывание является выполнение подпрограммы, адрес начала которой, или вектор прерывания, находится в таблице, номер строки которой и есть номер прерывания. Максимальное количество прерываний для процессоров Intel – 256.
К подпрограммам DOS и BIOS доступ осуществляется по прерываниям. Связано это с тем, что в разных версиях адреса начала различных подпрограмм могут начинаться с разных адресов. А так как таблицу векторов прерываний формирует сама ОС, то достаточно только зафиксировать назначение строк таблицы, а ее содержание может изменяться.
В IBM-совместимых компьютерах не все вектора прерываний распределены между событиями и устройствами. Неиспользуемые номера и предназначены для обращения к подпрограммам ОС.
Так как свободных прерываний не много, то по одному вектору может вызываться несколько подпрограмм. Номер подпрограммы, называемый функцией или службой прерывания, передается в качестве параметра, записываемого в регистр АН. Например, наиболее часто используемое прерывание DOS 21Н имеет 87 служб.
Подпрограммы DOS имеют более высокий уровень обработки информации и часто дополнительно используют прерывания BIOS.
Основные прерывания DOS:
21Н – общие функции DOS;
25Н – безусловное чтение с диска;
26Н – безусловная запись на диск.
Основные прерывания BIOS:
10Н – работа с видеосистемой;
12Н – получение размера основной памяти;
13Н – работа с дисками;
14Н – работа с последовательными портами;
15Н – разнообразные службы;
16Н – работа с клавиатурой;
17Н – работа с принтером;
19Н – перезагрузка компьютера;
1АН – работа с часами реального времени.
Иногда возникает ситуация, когда в программе необходимо определить собственные алгоритмы реакции на прерывания от внешних устройств или операционной системы, отменив при этом стандартные реакции.
Процедура, которая будет обслуживать прерывание, должна иметь директиву interrupt и строго фиксированный список параметров:
Procedure <имя> (Flags,
CS,IP,AX,BX,CX,DX,SI,DI,DS,ES,BP:Word);
interrupt;
Допускается отсутствие или задание отдельных параметров. Содержимое регистров процессора передается в процедуру в качестве параметров, поэтому их можно изменять.
Собственно переопределение некоторого прерывания производится обращением к процедуре модуля DOS:
SetIntVec (IntNo:byte; Vector:Pointer);
IntNo – номер прерывания, которое необходимо переопределить;
Vector – адрес новой процедуры обработки прерывания, которая будет запускаться автоматически.
При завершении программы желательно восстанавливать все переопределения, которые делались программой, включая и старые обработчики прерываний. Для сохранения предыдущей реакции, то есть адреса начала подпрограммы, используется процедура
GetIntVec (IntNo:byte; Var Vector:Pointer);
которая присваивает второму параметру адрес текущей реакции на прерывание с номером IntNo.
Таким образом, несколько программ могут работать с одним прерыванием: сначала срабатывает новый обработчик, затем управление передается следующему, расположенному по адресу Vector.
Программы, обрабатывающие прерывания, являются специфическими, так как обращение к ним происходит не из сегмента программ, а из таблицы прерываний. Поэтому для них необходимо указывать дальний (межсегментный) вызов директивой компилятора {$F+}.
Пример. Обработка прерывания, возникающего при нажатии клавиш Ctrl-Break.
Program Ctrl_Break;
{ Демонстрационный пример обработки прерывания,
возникающего при нажатии клавиш Ctrl-Break }
Uses Dos;
Const BreakFlag:boolean=False;
Var IntSt:pointer; { Адрес стандартного обработчика }
{$F+}
Procedure CtBr; interrupt;
Begin
BreakFlag:=true;
end;
{$F-}
Begin
{ Запоминаем адрес стандартной реакции }
GetIntVec($1b,IntSt);
SetIntVec($1b,@CtBr);
Writeln('Для окончания нажмите Ctrl-Break');
Repeat
Until BreakFlag;
{ Восстанавливаем первоначальный адрес реакции }
SetIntVec($1b,IntSt)
end.
-
Что такое «ассемблер»?
-
Что такое «макроассемблер»?
-
В каких случаях используется язык Ассемблер?
-
Что такое «встроенный ассемблер»?
-
Что такое «OBJ-файл»?
-
Какова структура asm-оператора?
-
Как в asm-операторах записываются комментарии?
-
Каков общий вид команды ассемблера (asm-оператора)?
-
Все ли регистры можно изменять в asm-операторах?
-
Как записываются локальные и глобальные метки в asm-операторах?
-
Какие коды инструкций (команд) используются во встроенном ассемблере?
-
Как обозначаются имена, совпадающие с зарезервированными словами?
-
Как в asm-операторах Паскаля в выражениях трактуется имя переменной?
-
Как в asm-операторах обозначается переменная с результатом функции?
-
С помощью какой директивы создается подпрограмма, полностью написанная на языке ассемблер?
-
Как можно напрямую обратиться к ячейкам памяти?
-
К ячейкам какого размера можно обращаться напрямую?
-
Как записывается адрес при обращении к ячейкам массива?
-
Как выполнить доступ к портам ввода-вывода?
-
Какой командой можно вызвать любое прерывание?
-
Что является реакцией процессора на прерывание?
-
Какой номер имеет наиболее часто используемое прерывание DOS?
-
Какую директиву должна иметь подпрограмма, обслуживающая прерывание?
-
Какова форма записи процедуры переопределения прерывания?
-
Какова форма записи процедуры восстановления прерывания?
Достарыңызбен бөлісу: |