Сегодня у нас будет очень короткий выпуск. Он посвящён использованию такой штуки, как Mem. Mem - это массив памяти. Т.е. с помощью указания номера элемента вы получаете доступ к определенной ячейке. существует 3 вида массива Mem:
- сам Mem - каждый компонент такого массива типа byte.
- MemW - каждый компонент типа word.
- MemL - каждый компонент типа longint.
- b := Mem [Seg:Ofs]; - в b байт с указанного адреса.
- w := MemW[Seg:Ofs]; - в w 2 байта с адреса
- l := MemL[Seg:Ofs]; - в l 4 байта
- Mem[Seg:Ofs] := b; - запишет 1 байт по адресу
- MemW[Seg:Ofs] := w; - запишет 2 байта по адресу
- MemL[Seg:Ofs] := l; - запишет 4 байта по адресу
begin
Mem[$B800:0] := 1;
Mem[$B800:1] := $84
end.
-рисует вместо первого символа красную мигающую рожицу на чёрном фоне. Если вы забыли, как устроена видеопамять в текстовом режиме или не читали об этом, то вам лучше вернуться к выпуску #16 Путешествие по памяти. Продолжим и сделаем тоже самое, но с использованием MemW:
begin
MemW[$B800:0] := $8401
end.
вот тут обратите внимание на тут тонкость о которой я говорил - запись идёт в обратном порядке.Если бы мы написали MemW[$B800:0] := $0184 - т.е. сначала символ, а потом аттрибут. То мы бы увидели синюю букву Д, а не красную рожицу. Давайте теперь изменим 4 байта в видеопамяти, т.е. 2 первых символа на экране с помощью MemL:
begin
MemL[$B800:0] := $24028401
end.
Опять таки обратите внимание на обратный порядок записи - сначала идёт байт-аттрибут 2-го символа, потом второй символ, потом байт-аттрибут 1-ог символа и наконец сам 1-й символ. Теперь давайте считывать из памяти. Напомня, что слово по адресу 0:413 содержит информацию BIOS'a о наличной памяти в килобайтах. Давайте распечатаем это число.
begin
writeLn (MemW[0:$413])
end.
в общем и целом тут нет ничего сложного. Поэтому думаю, что эту тему можно считать закрытой.
colspanЗадание
В прошлый раз я не дал объяснения как найти предыдущий элемент в списке с одной связью (list на входе указывает на текущий элемент списка, start на его начало). Ниже приводится текст процедуры с комментариями.
procedure findPrior;
var
l : plist;
begin
if (start = list) or (list = nil)then
exit; { предыдущего нет }
l := list; { сохраняем текущий в переменной l }
list := start;
{ перематываем список с начала }
while list <> nil do
begin
if list^.next = l then
exit; { нашли элемент, next которого указывает на текущий элемент, на выход }
list := list^.next
end
end;
если мы не смогли найти предыдущий элемент (например в случае если list принял ошибочное значение и вылез куда-то за границу списка), то при выходе list = nil. В случае удачного выполнения в list и окажется предыдущий элемент.

