Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Консп лек прог ЦТ и МК 2.doc
Скачиваний:
30
Добавлен:
01.05.2015
Размер:
897.54 Кб
Скачать

7 Лекция 7. Выполнения умножения и деления

Цель лекции: создать подпрограммы для целочисленного умножения и деления.

7.1 Умножение и деление при помощи сдвига.

Умножение числа на N-ю степень двойки реализуется сдвигом исходного зна­чении на N позиций влево. Таким образом, последовательность операций (00110 (6) << 01100 (12) << 11000 (24)), эквивалентна умножению числа 6 на 4. Оператор «<<» используется для обозначения сдвига влево. Это же правило примени­мо и к отрицательным числам

Аналогичным образом деление числа на N-ю степень двойки реализуется сдвигом значения на N позиций вправо, т.е. 1100 (12)>> 0110 (6) >> 0011 (3). Этот же способ применим также к знаковым числам.

Обратите внимание, что освободившиеся при сдвиге влево позиции заполня­ются не нулями, а содержимым знакового бита. Таким образом, при сдвиге поло­жительных чисел слева вдвигаются нули, а при сдвиге отрицательных чисел — единицы. Данная операция известна как арифметический сдвиг вправо, в отличие от логического сдвига вправо, при котором всегда вдвигаются нули.

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

В алгоритмах умножения и деления применяются инструкции условных переходов для ветвления.

Инструкции условных переходов BTFSC и BTFSS проверяют состояние заданного бита в любом регистре и в зависимости от результата, пропускают или не пропускают следующую инструкцию программы. Инструкция BTFSC пропускает следующую инструкцию, если заданный бит сброшен. В реальных программах вместо указанных инструкций пишутся инструкции, соответствующих разработанному алгоритму.

7.2 Инструкции условных переходов.

Т а б л и ц а 7.1 - Использование битов CARRY (C) и ZERO (Z).

Использование бита CARRY (C)

BTFSS STATUS, C

GOTO METKA

MOVWF R2

Если в бите Carry установлена единица, то пропускается следующая инструкция программы GOTO МЕТКА и сразу выполняется инструкция MOVWF R2

Если бит Carry сброшен, то выполняется следующая инструкция программы GOTO METKA

Использование бита ZERO (Z)

BTFSS STATUS, Z

CALL SDVIG

MOVWF PORTC

Если в бите Zero установлена единица, то пропускается следующая инструкция программы CALL SDVIG и сразу выполняется инструкция MOVWF PORTC

Если бит Zero сброшен, то выполняется следующая инструкция программы CALL SDVIG и затем MOVWF PORTC

7.3 Целочисленное умножение.

Умножение можно выполнить последовательным сложением, а деление – вычитанием, но при этом необходимо как-то сравнивать два числа. В ассемблере отсутствуют инструкции сравнения чисел. Чтобы определить, какое из чисел больше (меньше), применяют такой алгоритм:

1. Выполняют вычитание чисел. При этом в зависимости от результата, устанавливаются флаги C и Z регистра Status, см. таблицу 7.2.

2. Далее применяют инструкции условных переходов.

Т а б л и ц а 7.2 – Регистрация событий в регистре Status

Соотношения значений в W и РОН UMENSH

Значения флагов регистра Status после выполнения вычитания

Флаг Z

Флаг C

UMENSH-W>0

0 -Нулевого результата не было

1 - был перенос из 7 бита W в бит С (при сложении в дополнительном коде)

UMENSH-W<0

0 - Нулевого результата не было

0 - не было переноса из 7 разряда W в бит С (при сложении в дополнительном коде)

UMENSH-W=0

1 - был нулевой результат операции

1- был перенос из 7 разряда W в бит С (при сложении в дополнительном коде)

П р и м е ч а н и е – В регистр UMENSH помещается уменьшаемое число

Напишем подпрограмму выполнения умножения последовательным сложением. Например, чтобы умножить 25 на 10 нужно выполнить десять раз сложение: 25*10=25+25+25+25+25+25+25+25+25+25=250.

Umnozhenie; подпрограмма. Входы Umn_Chislo и Mnozh, выход Pr.

Clrf Pr

Clrf Kol_slag

Sled_slag

Movf Pr, W; загружаем Pr в W.

Addwf Umn_Chislo, W; добавление очередного слагаемого.

Movwf Pr

Incf Kol_slag, F; отмечаем количество сложений.

MOVF Kol_slag, W

XORWF Mnozh, F; маскированием проверяем Kol_slag=Mnozh.

Btfss STATUS, Z; проверяем Z=1?

Goto Sled_slag; выполняется только при Z=0.

RETURN

7.4 Целочисленное деление

Алгоритм целочисленного деления показан в таблице 7.3. Из алгоритма видно, что, если делитель равен нулю, то программа зациклится.

Таблица 7.3 - Алгоритм целочисленного деления

Цикл

Частное

Рабочий регистр

Действие

Рабочий регистр

Значение бита «С»

С=0?

Действие

1

1

35

Rab_peg= Rab_peg- Delitel

25

1

Нет

Повторяем цикл

2

2

25

15

1

Нет

Повторяем цикл

3

3

15

5

1

Нет

Повторяем цикл

4

4

5

-5

0

Да

Возвращаемся назад на 1 шаг

3

5

Остаток=5

Результат деления: частное=3, остаток =5, т.е. 35/10=3 (5)

Delenie; подпрограмма. Входы Delimoe и Delitel, выходы Chastnoe и Ostatok.

CLRF Chastnoe

Movf Delimoe, W;

MOVWF Rab_peg; копируем Delimoe в рабочий регистр.

MOVF Delitel, W; копируем Delitel в W.

BTFSC STATUS, Z; защита от деления на нуль.

GOTO NUL; выполняется только при Z=1.

Metka INCF Chastnoe, F; накапливаем частное.

SUBWF Rab_peg, F; вычитаем Rab_peg=Rab_peg-Delitel.

BTFSC STATUS, C; проверяем разность отрицательная?

GOTO Metka; выполняется только при C=1.

; Было выполнено одно лишнее вычитание. Возвращаемся на один шаг.

DECF Chastnoe, F; восстанавливаем частное.

ADDWF Rab_peg, W; восстанавливаем предыдущее значение Rab_peg.

MOVWF Ostatok; запоминаем остаток.

RETURN

NUL MOVLW D'255'; защита от деления на ноль.

MOVWF PORTC; сигнализируем о зацикливании программы.

END

7.5 Умножение на дробное число.

Умножение на дробное число можно выполнить с точностью до целых с помощью умножения заданного числа на целое число (множитель), и затем деления результата на другое целое число (делитель). Множитель и делитель подбираются на калькуляторе или MSExcel.

Пример. Выполним умножение числа 6 на 0,8. Сначала на калькуляторе подберем целочисленный множитель и целочисленный делитель, таким образом, чтобы получить примерно заданный коэффициент. В данном случае подходят множитель 4 и делитель 5, поскольку 4/5=0,8. Далее умножаем заданное число на четыре, и затем результат делим на пять. Остаток будет определять погрешность проведенных вычислений.