ZX Review
#3-4
22 июля 1997 |
|
Этюды - В.Сироткин. Программа подсчета контрольной суммы.
(c) В.Сироткин, г.Краснокаменск. Программа подсчета контрольной суммы. В некоторых программах прямой необходимостью является контро- лирование правильности и целост- ности блока данных, загружаемого или сохраняемого на диск. Также может быть необходим динамичес- кий контроль части самой прог- раммы. Эту проблему можно решить подсчетом контрольной суммы. Есть разные алгоритмы и раз- ные подходы, но самым действен- ным из всех является метод ЦИК- ЛИЧЕСКОГО ИЗБЫТОЧНОГО КОДА (CRC). Алгоритм CRC применяется в IBM-программах и позволяет выяв- лять ошибки с точностью до бай- та. Ниже дан листинг процедуры, подсчитывающей контрольную сум- му алгоритмом CRC. (Пример взят из журнала 'РАДИО' за 1992 год и дается без комментариев). 148. ;--- входные параметры: ; HL -начальный адрес блока ; DE -конечный адрес блока ;--- выходные данные: ; BC -контрольная сумма блока LEN DEFB 0 START PUSH HL INC DE XOR A LD (LEN),A LD BC,0 MET1 PUSH DE LD A,C XOR (HL) LD E,A PUSH BC PUSH HL LD BC,00 LD D,8 MET2 PUSH BC LD A,C RRA LD A,B RRA LD B,A LD A,C RRA LD C,A POP HL LD A,E XOR L AND 1 JR Z,MET3 LD A,B XOR #A0 LD B,A LD A,C XOR 1 LD C,A MET3 LD A,E RRCA AND #7F LD E,A DEC D JR NZ,MET2 POP HL POP DE LD A,D XOR C LD C,A LD A,E XOR B LD B,A LD A,(LEN) INC A LD (LEN),A INC HL POP DE LD A,H CP D JR NZ,MET1 LD A,L CP E JR NZ,MET1 DEC DE POP HL RET 2 Данная подпрограмма переме- щаема, т.е. может работать в лю- бых адресах, если Вы, конечно, определите адрес с меткой 'LEN' куда-нибудь за пределы подпрог- раммы. Достаточно точно отслеживает- ся изменение байтов в обсчиты- ваемой области. Замечается даже перестановка рядом лежащих бай- тов. Что касается быстродей- ствия, то блок длиной в 48 кило- байт обсчитывается за 5 сек. Арифметические вычисления. Как Вы знаете, в ПЗУ SOS встроена мощная программа КАЛЬ- КУЛЯТОР, которая позволяет про- изводить как простые арифмети- ческие действия, так и действия с плавающей запятой и тригоно- метрические вычисления. Но для работы КАЛЬКУЛЯТОРА необходима особая область - СТЕК КАЛЬКУЛЯТОРА, да и работа с калькулятором довольно сложна и утомительна, особенно в програм- мах, затирающих всю область ОЗУ. Иногда же требуются короткие, но действенные подпрограммы, вы- полняющие арифметические дей- ствия над байтами. Далее представлены несколько подпрограмм, которые позволяют обойтись без встроенного КАЛЬКУ- ЛЯТОРА. Все подпрограммы могут работать в любом месте ОЗУ, т.е. релоцируемы. Сложение N-байтовых положи- тельных чисел. Для того, чтобы сложить два числа длиною в N байтов, необхо- димо в регистр "B" занести коли- чество байтов в слагаемых. Сла- гаемые заносятся изначально в область с метками FIRST и SECND. Результат поместится в область с меткой FIRST. 148. ; Подпрограмма сложения многобайтных беззнаковых ; чисел ADDN LD B,N ; в "B" - сколько байтов надо ; сложить LD DE,FIRST ; адрес первого слагаемого LD HL,SECND ; адрес второго слагаемого XOR A ; флаг переноса сбросим SUM LD A,(DE) ; загрузим первый (младший) ; байт числа ADC A,(HL) ; сложим со вторым числом LD (DE),A ; сохраним результат DEC B ; все байты сложены ? RET Z ; если все, то конец INC HL ; нет, продолжим сложение INC DE JR SUM ; - - N EQU ? ; сколько байт складывать ? FIRST DEFB ? ; область длиною в (?) байт ; для первого числа SECND DEFB ? ; область для второго числа ; длиною (?) УМНОЖЕНИЕ однобайтных целых положительных чисел. ; Множимое заносится в регистр 'D' ; Множитель в регистр 'C' ; Результат в регистре 'BC' START LD B,0 ; сброс старшего байта ; результата LD E,8 ; число битов в байте NXBIT LD A,C ; множитель RRA ; очередной бит в флаге 'C' LD C,A ; вернем множитель DEC E ; счетчик уменьшим RET M ; все биты ? ДА- выйдем LD A,B ; старший байт результата JR NC,NOADR ; флаг 'C'множителя =0 ADD A,D ; суммируем множитель NOADR RRA ; сдвинем частичную сумму LD B,A ; вернем старший байт JR NXBIT ; умножение следущего бита ПРОГРАММА ДЕЛЕНИЯ ОДНОБАЙТНЫХ ЦЕЛЫХ ПОЛОЖИТЕЛЬНЫХ ЧИСЕЛ. ; делимое помещают в регистр 'E' ; делитель помещают в регистр 'D' ; частное получается в регистре 'H' ; в регистре 'C' образуется положительный остаток от ; деления START LD HL,08 ; 8 бит в байте LD C,0 ; сброс регистра остатков NEXT LD A,E ; делимое сдвинем RLA ; влево LD E,A ; на 1 бит LD A,C ; сдвиг остатка RLA ; влево на 1 бит SUB A,D ; вычтем делитель JR NC,NOADR ; остаток положительный ? ADD A,D ; востановление отрицательного ; остатка NOADR LD C,A ; остаток запомним CCF ; образуем бит частного LD A,H ; запоминание RLA ; очередной LD H,A ; цифры частного DEC L ; декремент счетчика битов JR NZ,NEXT ; цикл RET ; выход ;3 подпрограмма выполняется за 660 тактов. ПРОГРАММА УМНОЖЕНИЯ ЦЕЛОГО ОДНОБАЙТНОГО ЧИСЛА НА ЦЕЛОЕ ДВУХБАЙТНОЕ ЧИСЛО (числа положительные). ; 2-х байтное множимое поместить в 'DE' ; 1-байтный множитель в 'A' ; результат получим в регистрах : ; в 'A' старший байт произведения ; в 'HL' младшие 16 бит произведения START LD HL,0 ; сброс регистра произведения LD C,8 ; счетчик битов NXBIT ADD HL,HL ; частичная сумма RLA ; сдвинем множитель JR NC,NOADR ; анализ бита множителя ADD HL,DE ; суммируем множимое NOADR ADC 0 ; учет переноса DEC C ; все 8 бит множителя ? JR NZ,NXBIT ; нет, продолжим RET ; выход ;------------------------------ 2 ПРЕОБРАЗОВАНИЕ ДВОИЧНОГО ЧИСЛА В ДВОИЧНО-ДЕСЯТИЧНОЕ. Для отображения результатов вычислений необходимо числа привести в удобный для вывода вид, т.е. преобразовать число в десятичный код. Например, двоич- ное число 00001111 (#0F) удобно представить в виде 0001 0101 (#15), т.е. преобразовать его в двоично-десятичную форму. Этим занимается следующая подпрограм- ма. 148. ; BCD2B- подпрограмма перевода 2-х байтного числа. ; Двоичное число должно быть в регистре 'HL'. ; Результат : ; в 'A' - десятки тысяч; ; в 'B' - тысячи и сотни; ; в 'C' - десятки и единицы. ; Во время работы вызывается процедура CONV из ; подпрограммы BCD1B - перевод однобайтного числа, ; в которой; ; в 'H' - число для перевода , 'L'=0 ; Результат работы: в 'A' - разряды сотен; ; в 'B' - десятки и единицы ; Вход в процедуру преобразования 2-х байтного числа: BCD2B LD E,17 ; счетчик 1-го цикла CALL CONV ; вычислить младший BCD байт LD C,A ; сохранить в 'C' LD E,17 ; счетчик 2-го цикла JR PRODOL ; переход на вычисление ; процедура для преобразования 1-байтного числа BCD1B LD E,9 ; цикл для 1-байтного числа PRODOL CALL CONV ; вычислить два старших байта LD B,A ; сохранить средний байт LD A,L ; старший байт RET ; выйти вообще ;----- CONV XOR A ; очистить SBIT DEC E ; уменьшим счетчик цикла RET Z ; цикл весь - выйти ADD HL,HL ; сдвинем старшие разряды в ; перенос ADC A,A DAA ; скорректируем JR NC,SBIT ; результат больше 99 ? INC HL ; да - увеличим на 1 JR SBIT ; вернемся в вычисления 2 ********************************
Другие статьи номера:
Похожие статьи:
В этот день... 21 ноября