Специальные адреса памяти
В ОС MS-DOS имеются специальные адреса памяти, которые используются системой и с помощью которых можно выполнять, например, операции по обслуживанию периферийных устройств. Эти адреса расположены в сегменте, для доступа к которому используется константа Seg0040.
Таблица 1. Некоторые специальные адреса MS-DOS
-
смещение
размер
Назначение
$0010
word
список оборудования
$0017
word
статус клавиатуры
$0019
word
альтернативный ввод с клавиатуры
$001A
word
вершина буфера клавиатуры
$001C
word
нижняя часть буфера клавиатуры
$001Е
16*word
буфер клавиатуры - кольцевой список
В таблице 2 приведено описание байта состояния клавиатуры (адрес $0040:$0017). Установка каждого бита в этом байте соответствует наступлению определенного события.
Таблица 2. Байт состояния клавиатуры
-
Бит
событие
0
нажата правая клавиша Shift
1
нажата левая клавиша Shift
2
нажата клавиша Ctrl
3
нажата клавиша Alt
4
нажата клавиша ScrollLock
5
нажата клавиша NumLock
6
нажата клавиша CapsLock
7
нажата клавиша Insert
Шестнадцатеричная константа $DF, в двоичной записи имеющая вид 1101 1111, играет роль маски. Побитовое выполнение логической операции and над этой константой и байтом состояния клавиатуры устанавливает значение 5-го бита (‘режим NumLock включен’) в 0, т.е. отключает его.
Переменная Absolute
В языке Паскаль имеется возможность размещать переменные по конкретным адресам оперативной памяти. Такие переменные называются абсолютными и обычно используются в системных программах. Для описания абсолютных переменных предназначено зарезервированное слово Absolute. Формат:
Var <идентификатор> : <тип> Absolute BA:BS;
где BA – базовый адрес сегмента, BS смещение внутри этого сегмента. Например, Var root : integer Absolute $0000:$01F0;
BA:BS может заменяться на идентификатор другой переменной, тогда вместо BA:BS будет подставлен ее адрес. Таким способом можно выполнять ‘наложение’ переменных.
Пример. Программа образует строку букв алфавита путем ее увеличения в цикле на одну букву, начиная с латинской буквы ‘a’.
Var
str:string[10];
len: byte absolute str; {len налагается на str, т.е. len будет содержать значение первого байта переменной str, содержащего текущую длину строки}
i:integer;
c:char;
Begin
c:='a';
str:='a';
writeln(str);
writeln('length of string =',len);
for i:=1 to 3 do
begin
str:=str+succ(c);
writeln(str);
writeln('length of string =',len);
c:=succ(c);
end;
readln
End.
Результат работы:
a
length of string = 1
ab
length of string = 2
abc
length of string = 3
abcd
length of string = 4
Для работы с абсолютными переменными в языке Паскаль имеется ряд стандартных подпрограмм:
Addr(Id) – возвращает адрес расположения первого байта переменной с идентификатором Id. Результат имеет длину два слова и содержит базовый адрес и величину смещения.
Ofs(Id) – возвращает величину смещения в сегменте первого байта указанной переменной, процедуры или функции, определяемой Id. Результат имеет целочисленное значение.
Seg(Id) – возвращает адрес сегмента, содержащего первый байт переменной с идентификатором Id. Результат имеет целочисленный тип.
CSeg – возвращает базовый адрес сегмента кода. Результат имеет целочисленный тип.
DSeg – возвращает базовый адрес сегмента данных. Результат имеет целочисленный тип.
