8.6. Поиск строки
Длина: 155
Количество переменных: 2
Контрольная сумма: 17221
Назначение: эта программа осу-
ществляет поиск по БЕЙСИК-прог-
рамме и выводит каждую строку,
содержащую набор символов, опре-
деленных пользователем.
Переменные:
Имя: data start
Длина: 2
Ячейка: 23296
Комментарий: адрес первого
байта данных.
Имя: string length
Длина: 1
Ячейка: 23298
Комментарий: число симво-
лов в строке.
Вызов программы:
RANDOMIZE USR адрес
Контроль ошибок: если в памя-
ти нет БЕЙСИК-программы или сим-
вольная строка имеет нулевую
длину - возврат в BASIC.
Комментарий: время выполнения
этой программы пропорционально
двум величинам: длине строковой
переменной и длине БЕЙСИК-прог-
раммы. Строка для поиска должна
быть помещена в ячейку выше
RAMTOP, а адрес первого байта
строки должен быть помещен в
ячейки 23296/7. Длина строки
должна быть сохранена в ячейке
23298.
ЛИСТИНГ МАШИННЫХ КОДОВ
МЕТКА АССЕМБЛЕР ЧИСЛА ДЛЯ ВВОДА147.
RES 0,(IY+2) 253 203 2 134
LD IX,(23296) 221 42 0 91
LD HL,(23635) 42 83 92
RESTAR LD A,(23298) 58 2 91
LD E,A 95
CP 0 254 0
RET Z 200
PUSH HL 229
RESTOR PUSH IX 221 229
POP BC 193
LD D,0 22 0
INC HL 35
INC HL 35
INC HL 35
CHECK INC HL 35
PUSH DE 213
LD DE,(23627) 237 91 75 92
AND A 167
SBC HL,DE 237 82
ADD HL,DE 25
POP DE 209
JR C,ENTER 56 4
POP HL 225
RET 201
LONG_J JR RESTAR 24 223
ENTER LD A,(HL) 126
CP 13 254 13
JR NZ,NUMBER 32 5
INC HL 35
POP BC 193
PUSH HL 229
JR RESTOR 24 221
NUMBER CALL 6326 205 182 24
JR NZ,COMPAR 32 8
DEC HL 43
DIFFER PUSH IX 221 229
POP BC 193
LD D,0 22 0
JR CHECK 24 216
COMPAR LD A,(BC) 10
CP (HL) 190
JR NZ,DIFFER 32 245
INC BC 3
INC D 20
LD A,D 122
CP E 187
JR NZ,CHECK 32 206
LD A,13 62 13
RST 16 215
POP HL 225
PUSH HL 229
LD B,(HL) 70
INC HL 35
LD L,(HL) 110
LD H,B 96
LD DE,1000 17 232 3
LD A,47 62 47
THOUS INC A 60
AND A 167
SBC HL,DE 237 82
JR NZ,THOUS 48 250
ADD HL,DE 25
RST 16 215
LD DE,100 17 100 0
LD A,47 62 47
HUNDR INC A 60
AND A 167
SBC HL,DE 237 82
JR NC,HUNDR 48 250
ADD HL,DE 25
RST 16 215
LD DE,10 17 10 0
LD A,47 62 47
TENS INC A ! 60
AND A 167
SBC HL,DE 237 82
JR NC,TENS 48 250
ADD HL,DE 25
RST 16 215
LD A,L 125
ADD A,48 198 48
RST 16 215
POP HL 225
INC HL 35
INC HL 35
INC HL 35
140.
NEXT_C INC HL 35
LD A,(HL) 126
LINEND CP 13 254 13
JR NZ,CHR_14 32 4
RST 16 215
INC HL 35
JR LONG_J 24 155
CHR_14 CALL 6326 205 182 24
JR Z,LINEND 40 243
CP 32 254 32
JR C,NEXT_C 56 237
RST 16 215
JR NEXT_C 24 23
2
Как она работает:
Бит 0 байта, хранящегося по
адресу 23612, сбрасывается, что-
бы символы, выводимые на печать,
появлялись в верхней части экра-
на. В IX загружается адрес пер-
вого байта данных. Это позво-
ляет загрузить этот адрес в дру-
гую пару регистров, используя в
меньшей степени буфер принтера.
В HL загружается адрес начала
БЕЙСИК-программы.
В аккумулятор загружается дли-
на эталонной строки и это значе-
ние копируется в E-регистр. Если
длина строки равна 0, программа
возвращается в BASIC. Адрес в HL
помещается в стек, храня положе-
ние искомой в настоящий момент
строки в памяти.
Адрес данных копируется из IX
в BC для большей доступности. В
D-регистр загружается 0, т.е.
количество найденных символов,
равнозначных введенным данным.
Пара регистров HL увеличивается
на 3, указывая на старший байт
указателя длины строки. HL уве-
личивается, указывая на следую-
щий символ. Пара регистров DE
сохраняется в стеке.
В DE загружается адрес облас-
ти переменных и это значение вы-
читается из HL. Если результат
отрицательный, программа перехо-
дит к ENTER после восстановле-
ния HL и возвращения из стека
DE. Если результат был положи-
тельным, стек восстанавливается
до своего первоначального разме-
ра и выполняется возврат в BA-
SIC, т.к. достигнут конец БЕЙ-
СИК-программы.
В процедуре ENTER в аккумуля-
тор загружается байт, хранящий-
ся по адресу в HL. Если это не
признак ENTER, происходит пере-
ход к NUMBER. Если признак ENTER
найден, HL увеличивается, указы-
вая на начало следующей строки.
Адрес предыдущей строки удаляет-
ся из стека и замещается новым
значением в HL. Затем делается
переход к RESTOR. В процедуре
NUMBER вызывается подпрограмма
ПЗУ, расположенная там по адре-
су 6326. Если символ в аккумуля-
торе является признаком NUMBER
(CHR_14), HL увеличивается, ука-
зывая на первый символ после пя-
тибайтного представления числа,
определенного подпрограммой ПЗУ.
Если признак NUMBER не обнару-
жен, программа переходит к
COMPAR, иначе HL уменьшается и
программа переходит к DIFFER. BC
копируется из IX, количество
найденных символов сбрасывается
в 0 и делается переход к CHECK.
В процедуре COMPAR в аккумуля-
тор загружается байт, хранящий-
ся по адресу в BC. Если это зна-
чение не то же самое, что и
байт, хранящийся по адресу в HL,
программа возвращается в DIFFER.
BC увеличивается, указывая на
следующий байт данных, и коли-
чество определенных символов
увеличивается. Если это значе-
ние не равно длине символьной
строки, программа возвращается к
CHECK.
В аккумулятор загружается код
признака ENTER, и это значение
выводится на печать, используя
команду RST 16. Адрес строки для
вывода на печать загружается из
стека в HL. Номер строки затем
копируется в HL через B-регистр.
В DE загружается 1000 и в акку-
мулятор загружается значение, на
1 меньшее, чем код символа 0.
Аккумулятор уменьшается, а DE
повторно вычитается из HL до тех
пор, пока HL не станет отрица-
тельным. Затем DE прибавляется к
HL, чтобы получить положительный
остаток. Символ из аккумулятора
выводится на печать.
Вышеописанный прием повторяет-
ся затем для DE=100 и DE=10. За-
тем остаток загружается в акку-
мулятор, прибавляется 48 и в ре-
зультате полученный символ выво-
дится на печать.
Адрес начала строки восстанав-
ливается из стека и загружается
в HL. Затем HL увеличивается,
указывая на старший байт указа-
теля длины строки, HL увеличи-
вается, и байт с адресом в HL
загружается в аккумулятор. Если
этот байт не является призна-
ком ENTER, делается переход к
CHR_14, иначе ENTER выводится на
печать. HL увеличивается и прог-
рамма возвращается к RESTAR.
В процедуре CHR_14 вызывается
подпрограмма ПЗУ по адресу 6326.
Если символ в аккумуляторе яв-
ляется признаком числа, HL уве-
личивается, указывая на первый
символ, стоящий после найденно-
го числа. Этот символ загружает-
ся в аккумулятор и делается пе-
реход к LINEND. Затем, если сим-
вол в аккумуляторе имеет код
меньший, чем 32, подпрограмма
возвращается к NEXT_C. Если код
больше, чем 31, найденный сим-
вол выводится на печать и прои-
содит переход к NEXT_C.