
- •Алматы 2011
- •1 Лекция 1. Микроконтроллеры в современном мире
- •2 Лекция 2. Выполнение арифметических операций в мп
- •3 Лекция 3. Регистры общего и специального назначения
- •4 Лекция 4. Косвенная адресация. Логика. Маскирование
- •5 Лекция 5. Маскирование. Стек
- •7 Лекция 7. Выполнения умножения и деления
- •8 Лекция 8. Программирование клавиатуры. Дешифратор.
- •9 Лекция 9. Основные элементы цифровой техники
- •10 Лекция 10. Структура микроконтроллера, 2-10 система
- •11 Лекция 11. Прерывания и сторожевой таймер
- •12 Лекция 12. Фактор времени и аналоговый мир
- •Приложение а Список некоторых сокращений
- •Литература
- •Оглавление
- •0 50013, Алматы, Байтурсынова, 126
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. Далее умножаем заданное число на четыре, и затем результат делим на пять. Остаток будет определять погрешность проведенных вычислений.