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.