40 ЛУЧШИХ ПРОЦЕДУР
Окончание. Начало см. с. 17-28, 61-70, 105-110.
8.5 Составление списка переменных.
Длина: 94
Количество переменных: 0 Контрольная сумма: 10295 Назначение:
Эта подпрограмма составляет список имен всех переменных, имевшихся в настоящий момент в памяти.
Вызов программы:
RANDOMIZE USR адрес Контроль ошибок:
Если переменных в памяти нет, программа возвращается в BASIC. Комментарий:
Это большая помощь при отладке программ, особенно длинных и сложных.
ЛИСТИНГ МАШИННЫХ КОДОВ
ЧИСЛА ДЛЯ ВВОДА
253 203 2 134 42 75 92
13 62 13 215
32 62 32 215 126
254 128 200
203 127 40 62 203 119 40 31 203 111 40 9
214 128
17 19 0
215 25
24 225
214 96
215
62 36 215
62 4 0 215
62 41 35 94 35 86 35
24 234
МЕТКА АССЕМБЛЕР
RES 0,(IY+2) LD HL,(23627) N_VAR LD A,
RST 16 LD A, RST 16 LD A,(HL) CP 128 RET Z BIT 7,А JR Z,BIT_5 BIT 6,A JR Z,N_BIT BIT 5,А JR Z,STR_AR SUB 128 LD DE,19
PRINT RST 16
ADD HL,DE JR N_VAR STR_AR SUB 96 RST 16 LD A, 36 BRACK RST 16
LD A,40 RST 16 LD A,41
POINT INC HL
LD E,(HL) INC HL LD D,(HL) INC HL JR PRINT
BIT 5,A JR Z,ARRAY
SUB 64 RST 16 INC HL LD A,(HL) BIT 7,A
JR NZ,LAST_C
RST 16 JR NEXT_C SUB 128 LD DE,6 JR PRINT SUB 32 JR BRACK BIT 5,A
17 6 0
24 211
214 32 24 216 203 111 32 243 198 32
215
JR NZ,JUMP
ADD A,32 RST 16 LD A, 36 JR POINT
Как она работает:
Бит 0 байта по адресу 23612 сбрасывается, чтобы символы, выводимые на печать, появлялись в верхней части экрана. В HL загружается адрес области переменных. В аккумулятор загружается признак ENTER и вызывается подпрограмма ПЗУ по адресу 16. В аккумулятор затем загружается код пробела, и вновь вызывается та же самая подпрограмма ПЗУ.
В аккумулятор загружается байт по адресу в HL. Если значение этого байта равно 128, программа возвращается в BASIC, т.к. достигнут конец области переменных.
Если бит 7 аккумулятора установлен в 0, программа переходит к 'BIT_5', т.к. встретились строковая переменная или число, имя которых состоит только из одной буквы. Проверяется 6 бит аккумулятора. Если он равен 0, делается переход к 'N_BIT', т.к. определены массив или число, имя которых более, чем одна буква. Если бит 5 аккумулятора равен 0, программа переходит к 'STR_AR'
Программа достигает этой точки, если найденная переменная является управляющей переменной цикла FOR/NEXT. В этом случае из аккумулятора вычитается 128 и результатом является код символа для вывода на печать. В пару DE загружается число 19, указывая на следующую переменную при прибавлении к HL. Символ в аккумуляторе выводится на печать, DE прибавляется к HL, а программа возвращается к поиску следующей переменной
'N VAR'.
Если программа находит строковый массив (достигает 'STR_AR'), то из аккумулятора вычитается число 96, что дает код имени найденного массива. Это значение выводится на печать, используя подпрограмму ПЗУ. Знак доллара и левая скобка выводятся на печать, а в аккумулятор загружается код правой скобки. HL увеличивается, указывая на байты, содержащие длину массива. Это значение загружается в DE, так что прибавление к HL дает адрес следующей переменной. Делается переход к 'PRINT', где правая скобка выводятся на печать, и DE прибавляется к HL.
В процедуре 'N_BIT' проверяется бит 5 аккумулятора. Если он установлен в 0, т.е. это числовой массив, то происходит переход к 'ARRAY. Если он установлен в 1, то это числовая переменная, имя которой длиннее, чем одна литера. Из аккумулятора вычитается 64, а полученный в результате символ выводится на печать. Затем программа выполняет цикл, выводя на печать каждый встретившийся символ, до тех пор, пока находится хоть один символ с битом 7, установленным в 1. Из кода этого последнего символа вычитается 128, в DE загружается смещение для следующей переменной, а программа переходит к 'PRINT'.
Если массив найден, 32 вычитается из аккумулятора, чтобы получить правильный код, и делается переход на поиск скобок ' BRACK'.
В процедуре 'BIT_5', если найдено число, имя которого имеет только одну букву,
программа возвращается к 'JUMP'.
Окончание подпрограммы работает, когда встречающиеся переменные - строковые. Прибавление 32 к аккумулятору дает код для вывода на печать. Наконец, в аккумулятор загружается код знака доллара и делается переход к 'POINT'
8.6 Поиск строки.
Длина: 155
Количество переменных: 2 Контрольная сумма: 17221 Назначение:
Эта программа осуществляет поиск по БЕЙСИК программе и выводит каждую строку, содержащую набор символов, определенных пользователем.
Переменные: Имя - data start Длина - 2 Адрес 23296
Комментарий: адрес первого байта данных. Имя - string length Длина - 1 Адрес - 23298
Комментарий: число символов в строке.
Вызов программы:
RANDOMIZE USR адрес Контроль ошибок:
Если в памяти нет БЕЙСИК-программы или символьная строка имеет нулевую длину -возврат в БЕЙСИК. Комментарии:
Время выполнения этой программы пропорционально двум величинам: длине строковой переменной и длине БЕЙСИК программы. Строка для поиска должна быть помещена в ячейку выше RAMTOP, а адрес первого байта строки должен быть помещен в ячейки 23296/7. Длина строки должна быть сохранена в ячейке 23298.
ЛИСТИНГ МАШИННЫХ КОДОВ
ЧИСЛА ДЛЯ ВВОДА
253 203 2 134 221 42 0 91 42 83 92
58 2 91 95
МЕТКА АССЕМБЛЕР
RES 0,(IY+2) LD IX,(23296) LD HL,(23635)
RESTAR LD A,(23298)
LD E^ CP 0 RET Z PUSH HL
254 0
200 229
221 229 193
0 22 0
35 35 35 35 213
237 91 75 92 167
237 82 25
RESTOR PUSH IX
POP ВС LD D, INC HL INC HL INC HL
CHECK INC HL
PUSH DE LD DE,(23627) AND A SBC HL, DE ADD HL, DE
POP DE |
209 |
|
JR C,ENTER |
56 |
4 |
POP HL |
225 |
|
RET |
201 |
|
JR RESTAR |
24 |
223 |
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 |
CALL 6326 |
205 |
182 |
JRNZ COMPAR |
32 |
8 |
DEC HL |
43 |
|
PUSH IX |
221 |
229 |
POP BC |
193 |
|
LD D, |
0 |
22 |
JR CHECK |
24 |
216 |
LD A,(BC) |
10 |
|
CP (HL) |
190 |
|
JR NZ,DIFFER |
32 |
245 |
INC ВС |
3 |
|
INC D |
20 |
|
LD A, D |
122 |
|
CP E |
1 |
87 |
JR NZ,CHECK |
32 |
206 |
LD A, |
13 |
62 |
RST 16 |
215 |
|
POP HL |
225 |
|
PUSH HL |
229 |
|
LD B,(HL) |
70 |
|
INC HL |
35 |
|
LD L,(HL) |
110 |
|
LD H,В |
96 |
|
LD DE,1000 |
17 |
232 |
LD A,47 |
62 |
47 |
INC A |
60 |
|
AND A |
167 |
|
SBC HL,DE |
237 |
82 |
JR NC,THOUS |
48 |
250 |
ADD HL,DE |
25 |
|
RST 16 |
215 |
|
LD DE,100 |
17 |
100 |
LD A,47 |
62 |
47 |
INC A |
60 |
|
AND A |
157 |
|
SBC HL,DE |
237 |
82 |
JR NC,HUNDR |
48 |
250 |
ADD HL,DE |
25 |
|
RST 16 |
215 |
|
LD DE,10 |
17 |
10 |
LD A, |
47 |
62 |
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 |
|
24
0
47
0
1
3
0
INC HL NEXT_C INC HL
LD A,(HL) LINEND CP 13
35 35 126
254 13 32 4 215
JR NZ,CHR_14 RST 16 INC HL JR LONG_J
JR Z,LINEND CP 32
JR C,NEXT_C RST 16
24 234
Как она работает:
Бит 0 байта, хранящегося по адресу 23612 сбрасывается, чтобы символы, выводимые на печать, появлялись в верней части экрана. В IX загружается адрес первого байта данных. Это позволяет загрузить этот адрес в другую пару регистров, используя в меньшей степени буфер принтера. В HL, загружается адрес начала БЕЙСИК-программы.
В аккумулятор загружается длина эталонной строки, и это значение копируется в Е-регистр. Если длина строки равна 0, программа возвращается в БЕЙСИК. Адрес в HL помещается в стек, храня положение искомой в настоящий момент строки в памяти.
Адрес данных копируется из IX в BC для большей доступности. В D-регистр загружается 0, т. е. количество найденных символов, равнозначных введенным данным. Пара регистров HL увеличивается на 3, указывая на старший байт указателя длины строки. HL увеличивается, указывая на следующий символ. Пара регистров DE сохраняется в стеке.
В DE загружается адрес области переменных, и это значение вычитается из HL. Если результат отрицательный, программа переходит к 'ENTER' после восстановления HL и возвращения из стека DE. Если результат был положительным, стек восстанавливается до своего первоначального размера и выполняется возврат в БЕЙСИК, т. к. достигнут конец БЕЙСИК-программы.
В процедуре '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'.
ВС увеличивается, указывая на следующий байт данных, и количество определенных символов увеличивается. Если это значение не равно длине символьной строки, программа возвращается к 'CHECK'. В аккумулятор загружается код признака ENTER, и это значение выводится на печать, используя команду RST 16. Адрес строки для вывода на печать загружается из стека в HL, номер строки затем копируется в HL через В-регистр. В DE загружается 1000 и в аккумулятор загружается значение, на 1 меньшее, чем код символа "0". Аккумулятор уменьшается, a 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'.
8.7 Поиск и замещение строки.
Длина: 85
Количество переменных: 3 Контрольная сумма: 8518 Назначение:
Программа шлет символьную строку в БЕЙСИК-программе и делает замену каждой найденной строки стринга на другую строку такой же длины.
Переменные: Имя - old data start Длина - 2 Адрес - 23296
Комментарий: адрес первого байта замещаемой строки. Имя - string length длина - 1 Адрес - 23298
Комментарий: длина замещаемой строки. Имя - new data start Длина - 2 Адрес - 23299
Комментарий: адрес первого байта замещающей строки.
Вызов программы:
RANDOMIZE USR адрес Контроль ошибок:
Если длина строки равна 0 или БЕЙСИК-программы в памяти нет, то процедура возвращается непосредственно в БЕЙСИК. Комментарий:
Время выполнения этой программы зависит от длины строки и от длины БЕЙСИК-программы.
ЛИСТИНГ МАШИННЫХ КОДОВ
АССЕМБЛЕР |
ЧИСЛА ДЛЯ |
ВВОДА |
LD IX,(23296) |
221 |
42 |
0 |
LD HL,(23635) |
42 |
83 |
92 |
LD A,(23298) |
58 |
2 |
91 |
LD E,A |
95 |
|
|
CP 0 |
254 |
0 |
|
RET Z |
200 |
|
|
DEC HL |
43 |
|
|
INC HL |
35 |
|
|
INC HL |
35 |
|
INC HL |
35 |
|
INC HL |
35 |
|
JR RESET |
24 |
23 |
INC HL |
35 |
|
PUSH DE |
213 |
|
LD DE,(23627) |
237 |
91 |
AND A |
167 |
|
SBC HL,DE |
237 |
82 |
ADD HL,DE |
25 |
|
POP DE |
209 |
|
RET NC |
208 |
|
LD A,(HL) |
126 |
|
CP 13 |
254 |
13 |
JR Z,NEWLIN |
40 |
233 |
CALL 6326 |
205 |
182 |
JR NZ, COMPAR |
32 |
8 |
DEC HL |
43 |
|
PUSH IX |
221 |
229 |
POP ВС |
193 |
|
LD D,0 |
22 |
0 |
JR CHECK |
24 |
226 |
LD A,(ВС) |
10 |
|
CP (HL) |
190 |
|
JR NZ,RESET |
32 |
245 |
INC ВС |
3 |
|
INC D |
20 |
|
LD A,D |
122 |
|
CP E |
187 |
|
JR NZ,CHECK |
32 |
216 |
PUSH HL |
229 |
|
LD D,0 |
22 |
0 |
AND A |
167 |
|
SBC HL,DE |
237 |
82 |
LD D, E |
83 |
|
LD BC,(23299) |
237 |
75 |
INC D |
20 |
|
INC HL |
35 |
|
DEC D |
21 |
|
JR Z, FINISH |
40 |
5 |
LD |
10 |
|
LD (HL),A |
119 |
|
INC ВС |
3 |
|
JR NEXT C |
24 |
247 |
POP HL |
225 |
|
JR RESET |
24 |
215 |
24
3
Как она работает:
В IX загружается адрес замещающей строки. Это значение должно быть выше RAMTOP. В HL загружается адрес начала программной области, а в аккумулятор загружается длина строки, которая копируется в Е-регистр для дальнейшего использования в программе. Если длина строки равна 0, программа возвращается в БЕЙСИК.
Устанавливается HL, указывая на старший байт следующего указателя БЕЙСИК-строки и делается переход к 'RESET'.
В процедуре 'CHECK' HL увеличивается, указывая на следующий символ. DE сохраняется в стеке и загружается адресом области переменных. Если HL не меньше, чем DE, конец программы достигнут, и после восстановления DE из стека программа возвращается в БЕЙСИК.
В аккумулятор загружается символ по адресу в HL, Если это значение является знаком ENTER, программа возвращается к 'NEWLIN'. Если аккумулятор не содержит знак NUMBER (символ 14), делается переход к 'COMPAR', иначе HL увеличивается на 5, так что HL указывает на пятый байт найденного числа.
В процедуре 'RESET' в BC загружается адрес строки для поиска. Регистр D устанавливается в 0 для хранения количества символов в строке, найденной к тому времени. Программа затем возвращается к 'CHECK'.
В процедуре 'COMPARE' в аккумулятор загружается символ строки, на который указывает пара регистров BC. Если это значение отличается от байта по адресу в HL, программа переходит к 'RESET'. BC увеличивается, указывая на следующий символ в строке, регистр D, счетчик, увеличивается. Если это значение не равно длине строки, программа возвращается к 'CHECK'.
Если строка найдена, HL сохраняется на стеке, так что программа начинает поиск для следующего случая с этого адреса. В DE загружается длина строки и это значение вычитается из HL, давая значение на единицу меньше, чем стартовый адрес. Длина строки затем загружается в D для использования ее в качестве счетчика. В BC загружается стартовый адрес замещающей строки, а регистр D увеличивается. Регистр HL увеличивается, указывая на следующую ячейку, а счетчик уменьшается.
Если счетчик равен 0, HL восстанавливается из стека и делается переход к 'RESET' для следующего случая. В аккумулятор загружается символ, на который указывает BC и это значение помещается в ячейку по адресу в HL. BC увеличивается, указывая на следующий символ, а программа возвращается к 'NEXT CHAR'.
8.8 Поиск подстроки.
Длина: 168
Количество переменных: 0
Контрольная сумма: 19875
Назначение:
Эта программа возвращает позицию подстроки (B$) в главной строке (A$) или 0 в случае ошибки.
Вызов программы: LET P = USR адрес контроль ошибок:
Если строка не существует или если длина подстроки равна нулю или если длина подстроки больше, чем длина главной строки, программа возвращает значение 0. Если ошибки нет, но подстрока не найдена в главной строке, программа также дает 0.
Комментарий:
После выхода из программы в машинных кодах переменная P (может быть использована любая другая переменная) будет хранить искомое значение. Строки, к которым делается обращение, не могут быть массивами данных. Для изменения используемых строк числа, отмеченные звездочкой, должны быть изменены. 66* - это подстрока, 65* - главная строка. Для изменения эти числа необходимо заменить кодами требуемых символов. Например, если Вы хотите найти позицию H$ в G$, то соответственно надо будет ввести 71 (код G) и 72 (код Н)
ЧИСЛА ДЛЯ ВВОДА
151
71
79
87
95
42 75 92 126
254 128 40 95 203 127 32 41 254 96 48 29
ЛИСТИНГ МАШИННЫХ КОДОВ
МЕТКА АССЕМБЛЕР
SUB A
LD B, А
LD B, А
LD D, A
LD E, A
LD HL,(23627)
N EXT_V LD A,(HL)
CP 128
JR Z,NOT_FD BIT 7, А
JR NZ,FOR_NX
CP 96
JR NC,NUMBER
CP 65 |
254 |
65* |
JR NZ,SUBSTR |
32 |
2 |
LD D, Н |
84 |
|
LD E, L |
93 |
|
CP 66 |
254 |
66* |
JR NZ,CHECK |
32 |
2 |
LD B,H |
68 |
|
LD C,L |
77 |
|
LD A,D |
122 |
|
OR E |
179 |
|
JR Z,STRING |
40 |
4 |
LD A,В |
120 |
|
OR C |
177 |
|
JR NZ,ROUND |
32 |
38 |
PUSH DE |
213 |
|
INC HL |
35 |
|
LD E,(HL) |
94 |
|
INC HL |
35 |
|
LD D,(HL) |
86 |
|
ADD HL, DE |
25 |
|
POP DE |
209 |
|
JR INCRS |
24 |
5 |
INC HL |
35 |
|
INC HL |
35 |
|
INC HL |
35 |
|
INC HL |
35 |
|
INC HL |
35 |
|
INC HL |
35 |
|
JR NEXT V |
24 |
206 |
CP 224 |
254 |
224 |
JR C, N BIT |
56 |
6 |
PUSH DE |
213 |
|
LD DE,18 |
17 |
18 |
JR ADD |
24 |
234 |
BIT 5,A |
203 |
111 |
JR Z,STRING |
40 |
225 |
INC HL |
35 |
|
BIT 7,(HL) |
203 |
126 |
JR Z,NEXT B |
40 |
251 |
JR NUMBER |
24 |
227 |
EX DE,HL |
235 |
|
INC HL |
35 |
|
INC HL |
35 |
|
PUSH HL |
289 |
|
PUSH HL |
229 |
|
INC ВС |
3 |
|
PUSH ВС |
197 |
|
LD |
10 |
|
LD E,A |
95 |
|
INC ВС |
3 |
|
LD |
10 |
|
LD D,A |
87 |
|
OR E |
179 |
|
JR Z,ZERO |
40 |
11 |
PUSH DE |
213 |
|
LD A,(HL) |
126 |
|
DEC HL |
43 |
|
LD L,(HL) |
110 |
|
LD H,A |
103 |
|
AND A |
167 |
|
SBC HL,DE |
237 |
82 |
JR NC,CONTIN |
48 |
8 |
POP ВС |
193 |
|
POP ВС |
193 |
|
POP ВС |
193 |
|
0
SUBSTR
CHECK
STRING
ADD
NUMBER
INCRS FOR NX
N_BIT NEXT_B
FOUND
ERROR |
POP ВС |
193 |
|
NOT_FD |
LD BC,0 |
10 |
0 |
|
RET |
201 |
|
CONTIN |
POP IX |
221 |
285 |
|
POP ВС |
193 |
|
|
EX DE,HL |
235 |
|
|
POP HL |
225 |
|
|
INC ВС |
3 |
|
|
INC BC |
3 |
|
SAVE |
INC HL |
35 |
|
|
PUSH HL |
229 |
|
|
PUSH ВС |
197 |
|
|
PUSH IX |
221 |
229 |
|
PUSH DE |
213 |
|
COMPAR |
LD A,(BC) |
10 |
|
|
CP (HL) |
190 |
|
|
JR Z,MATCH |
40 |
12 |
|
POP DE |
209 |
|
|
POP IX |
221 |
225 |
|
POP BC |
193 |
|
|
POP HL |
225 |
|
|
LD A,D |
122 |
|
|
OR E |
179 |
|
|
JR Z,ERROR |
40 |
225 |
|
DEC DE |
27 |
|
|
JR SAVE |
24 |
234 |
MATCH |
INC HL |
35 |
|
|
INC BC |
3 |
|
|
PUSH HL |
229 |
|
|
DEC IX |
221 |
43 |
|
PUSH IX |
221 |
229 |
|
POP HL |
225 |
|
|
LD A,H |
124 |
|
|
OR L |
181 |
|
|
POP HL |
225 |
|
|
JR NZ,COMPAR |
32 |
227 |
|
POP DE |
209 |
|
|
POP DE |
209 |
|
|
AND A |
167 |
|
|
SBC HL,DE |
237 |
82 |
|
POP DE |
209 |
|
|
POP DE |
209 |
|
|
POP DE |
209 |
|
|
AND A |
167 |
|
|
SBC HL, DE |
237 |
82 |
|
LD B^ |
68 |
|
|
LD C,L |
77 |
|
|
RET |
201 |
|
Как она работает:
В аккумулятор, пару регистров BC и пару регистров DE загружается 0. Позднее в программе в BC будет установлен адрес B$, а в DE будет установлен адрес A$. В HL загружается адрес начала области программных переменных.
В аккумулятор загружается байт из адреса, находящегося в HL. Если аккумулятор содержит число 128 программа переходит к 'NOT_FD', т.к. достигнут конец области программных переменных. Если бит 7 аккумулятора установлен в 1, делается переход к 'FOR_NX', так как найденная переменная - не строковая и не число, имя которого состоит только из одной литеры. Если аккумулятор содержит число большее, чем 95, делается переход к 'NUMBER'.
Для достижения этого этапа строка должна быть найдена. Если в аккумуляторе содержится число 65, определяется местонахождение строки A$, а содержимое HL копируется в DE. Если аккумулятор содержит число 66, определяется строка B$, a HL копируется в BC. Если DE не равно 0, и BC не равно 0, определяется местонахождение обеих строк, и программа переходит к 'FOUND'.
Если программа достигает процедуры 'STRING', DE сохраняется в стеке и загружается длиной найденной строки. Это значение прибавляется к адресу старшего байта указателей строки и сохраняется в HL.. DE восстанавливается из стека и делается переход к 'INCRS'.
В процедуре 'NUMBER' HL увеличивается в пять раз, указывая на последний байт найденного числа. HL затем увеличивается, указывая на следующую переменную, и происходит переход к 'NEXT_V'.
В процедуре 'FOR_NX', если аккумулятор содержит число меньше, чем 224, делается переход к 'N_BIT', т.к. встретившаяся переменная не является управляющей переменной цикла FOR-NEXT. Если значение аккумулятора больше, чем 223, то число 18 прибавляется к HL, указывая на последний байт переменной цикла и программа возвращается к 'INCRS'.
Если программа достигает 'N_BIT', и бит 5 аккумулятора установлен в 0, делается переход к 'STRING', чтобы загрузить в HL адрес следующей переменной, т.к. найден массив.
Если программа достигает 'NEXT_B', найдено число, имя которого больше одного символа по длине. Т.о., HL увеличивается до тех пор, пока не укажет на последний символ имени переменной, а затем делается переход к 'NUMBER'.
В процедуре 'FOUND' в HL загружается адрес строки A$, и это значение увеличивается дважды, чтобы получить адрес старшего байта указателей. Это значение затем сохраняется в стеке дважды. BC увеличивается, указывая на младший байт указателей подстроки B$. Адрес в BC затеи сохраняется в стеке, в DE загружается длина строки B$, и, если это значение равно 0, делается переход к 'ZERO'. Затем DE помещается в стек. В HL загружается длина строки a$, и, если это значение не меньше, чем DE, программа переходит к 'CONTIN'. Указатель стека затем восстанавливается, в BC загружается 0, и программа возвращается в БЕЙСИК.
В процедуре 'CONTIN' в IX устанавливается длина строки B$, а в BC помещается адрес младшего байта указателей для подстроки B$. В DE загружается разность длин строк A$ и B$, а в HL загружается адрес старшего байта указателей для A$. BC затем увеличивается дважды, чтобы получить адрес первого символа в подстроке B$. HL увеличивается, указывая на следующий символ строки A$. HL, ВС, IX и DE затем сохраняются на стеке. В аккумулятор загружается байт по адресу в ВС, и, если это значение равно значению байта по адресу в HL, делается переход к 'MATCH'. DE, IX, BC и HL затем восстанавливаются из стека. Если DE содержит 0, делается переход к 'ERROR', т.к. подстроки B$ нет в строке A$. Счетчик DE уменьшается, и программа возвращается к 'SAVE'.
Если программа достигает процедуры 'MATCH', HL и BC увеличиваются, указывая на следующий символ A$ и B$ соответственно. HL затем сохраняется в стеке. IX, счетчик, уменьшается и после восстановления HL из стека, если IX не содержит 0, программа возвращается к 'COMPAR'.
Для достижения этого этапа местонахождение подстроки B$ в строке A$ уже должно быть определено. Длина подстроки B$ вычитается из HL, а затем адрес старшего байта указателей для строки A$ вычитается из HL. Результат - это позиция подстроки B$ в строке A$. Это значение копируется в пару регистров ВС, и программа возвращается в БЕЙСИК.
Заканчивая печать книги Дж. Хардмана и Э. Хьюзона "40 лучших процедур", нам хотелось бы дать небольшой комментарий, который касается формата программных переменных в "Спектруме". Дело в том, что процедуры, представленные в этом последнем заключительном блоке широко оперируют с ними. Те, кто не имеют фирменную инструкцию по "Спектруму" (книга Виккерса), могут быть с этим форматом и не знакомы, а мы в своих работах до сих пор как-то к этому вопросу не обращались.
Те, кому этот вопрос интересен, могут прочитать комментарий на стр. 44.