logo
ZX-Review-1992-01-12

Маленькие хитрости

В этом разделе мы коснемся некоторых путей повышения быстродействия часто встречающихся операций.

Так, например, в предыдущей статъе мы с Вами затронули маленький вопрос об очистке 256 байтного буфера. Давайте посмотрим, как бы мы делали эту операцию, если бы программировали в машинном коде.

Мы бы загрузили в регистровую пару HL адрес NN, с которого начинается наш буфер. Затем в регистре B организовали бы счетчик на 256 байтов (FFH), обнулили бы аккумулятор командой XOR и затем в цикле поместили бы содержимое аккумулятора в ячейки буфера, на которые указывает HL. При этом на каждом шаге увеличивали бы HL на единицу.

Мы специально пишем столь подробно об этих элементарных вещах, потому что рассчитываем, что нас могут читать и те, кто только подумывает об освоении машинного кода.

LD HL,NN

(10)

LD B, FFH

(7)

XOR A

(4)

LOOP LD (HL),A

(7)*256

INC HL

(6)*256

DJNZ LOOP

(8)*256

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

Итак, приведенный выше пример займет: 21 + 21*256 = 5397 тактов, т.е. в среднем 21,08 такта на очистку одного байта в буфере.

Можно ли быстрее? Скорее проще, чем быстрее. Те, кто знают машинный код, осведомлены о наличии команды LDIR, которая служит для автоматической очень быстрой переброски блоков данных из одной области памяти в другую. Эта команда перебрасывает блок байтов, длина которого установлена в регистровой паре BC из области, начинающейся с адреса, установленного в регистровой паре HL в область, на начало которой указывает содержимое DE. Остается открытым вопрос, а как можно использовать LDIR для очистки, ведь если эта команда может быстро перебросить блок нулевых байтов, то ведь такой блок надо сначала создать в общем придем к тому, от чего ушли (мы не можем в общем случае рассчитывать на то, что где то в компьютере есть пространства с нулевым содержимым ячеек, откуда можно черпать "пустые" массивы).

Оказывается, использовать LDIR все же можно, хоть и делается это несколько необычно. Рассмотрим пример:

LD HL, NN

(10)

LD DE,NN+1

(10)

LD

BC, 00FFH

(10)

LD

(HL),B

(7)

LDIR

(21)*256

To, что здесь происходит, может показаться чепухой. В HL установили адрес начала нашего буфера, в DE адрес второго байта буфера, в BC счетчик на 255. Командой LD (HL),B очистили первый байт буфера, а потом зачем то передвинули все содержимое буфера на один байт вверх. Ну получим в итоге, что и второй байт станет нулевым, а дальше то что?

Вся хитрость состоит в том, что во время работы команды LDIR содержимое HL, DE и BC не остаются неизменными. После переброски каждого очередного байта HL и DE