Сумма
1 0 1 0 0 1Таким образом, если результат сложения есть отрицательное число, то оно оказывается представленным в дополнительном коде.
Для вычитания 8-разрядных чисел без знака
может быть использовано выражение , где – поразрядная инверсия . Другой способ вычитания может быть основан на следующем выражении: .Пример 1.6. Вычитание байтов. Операция вычитания может быть выполнена двумя способами: переводом вычитаемого как отрицательного числа в дополнительный код с последующим сложением; переводом уменьшаемого в обратный код с последующей инверсией суммы.
Пусть требуется вычесть из A содержимое регистра R6. Вычитание выполнить в соответствии с выражением
. Установка флага C после выполнения сложения будет свидетельствовать об отрицательном переполнении.CPL A ; инверсия аккумулятора
ADD A,R6 ; сложение
CPL A ; инверсия суммы (получение разности)
Пример 1.7. Получить разность 2-байтных чисел без знака. Операнды располагаются в РПД. Адрес уменьшаемого хранится в R1, а вычитаемого – в R0. Результат поместить на место уменьшаемого:
; вычисление Z = X–Y
; X, Y – РПД
; R0 – адрес Y
; R1 – адрес X
; результат на место X
SUBSTR: MOV A,@R0 ; загрузка младшего байта Y
CPL A ; получение дополнительного кода Y
INC A ;
ADD A,@R1 ; вычитание младших байт
MOV @R0,A ; запоминание младшего байта разности
INC R0 ; переход к старшим байтам X и Y
INC R1 ;
MOV A,@R0 ; загрузка старшего байта Y
CPL A ; обратный код Y
ADDC A,@R1 ; вычитание старших байт
MOV @R0,A ; запоминание результата
Умножение двоичных чисел. Пусть производится умножение чисел 11012 и 10112.
1 1 0 1 множимое
1 0 1 1 множитель
1 1 0 1 1-е частичное произведение
1 1 0 1 2-е частичное произведение
0 0 0 0 3-е частичное произведение
1 1 0 1 4-е частичное произведение
1 0 0 0 1 1 1 1 произведение
Как видно из примера, при выполнении умножения формируются частичные произведения (произведения множимого на цифры разрядов множителя), которые суммируются с соответствующими сдвигами друг относительно друга. В цифровых устройствах процессу суммирования частичных произведений придают последовательный характер: формируется одно из частичных произведений, к нему с соответствующим сдвигом прибавляется следующее частичное произведение, к полученной сумме двух частичных произведений прибавляется с соответствующим сдвигом очередное частичное произведение, и так далее, пока не будут просуммированы все частичные произведения. Этот процесс суммирования можно начинать с младшего либо старшего частичного произведения.
Ниже показаны процессы при умножении с суммированием частичных произведений, начиная со старшего частичного произведения (используется приведенный выше пример умножения чисел 11012 и 10112).
1 1 0 1 4-е частичное произведение
1 1 0 1 0 сдвиг на один разряд влево
0 0 0 0 3-е частичное произведение
1 1 0 1 0 сумма 4- и 3-го частичных произведений
1 1 0 1 0 0 сдвиг на один разряд влево
1 1 0 1 2-е частичное произведение
1 0 0 0 0 0 1 сумма 4-, 3- и 2-го частичных произведений
1 0 0 0 0 0 1 0 сдвиг на один разряд влево
1 1 0 1 1-е частичное произведение
1 0 0 0 1 1 1 1 произведение
Рассмотрим выполнение операции умножения с суммированием частичных произведений, начиная с младшего частичного произведения на примере умножения чисел 11012 и 10112.
1 1 0 1 1-е частичное произведение
0 1 1 0 1 сдвиг на один разряд вправо
1 1 0 1 2-е частичное произведение
1 0 0 1 1 1 сумма 1- и 2-го частичных произведений
1 0 0 1 1 1 сдвиг на один разряд вправо
0 0 0 0 3-е частичное произведение
1 0 0 1 1 1 сумма 1-, 2- и 3-го частичных произведений
1 0 0 1 1 1 сдвиг на один разряд вправо
1 1 0 1 4-е частичное произведение
1 0 0 0 1 1 1 1 сумма частичных произведений
1 0 0 0 1 1 1 1 сдвиг вправо, произведение
При умножении целых чисел для фиксации произведения в разрядной сетке должно предусматриваться число разрядов, равное сумме числа разрядов множимого и множителя.
Пример 1.8. Умножить однобайтные целые числа без знака. В регистре R1 размещен множитель, в регистре R2 – множимое. Двухбайтный результат умножения будет размещен в аккумуляторе (старший байт) и в R1 (младший байт) вместо множителя. В регистр R3, выполняющий функции счетчика программных циклов, загружается число 8 (число бит множителя). Умножение выполняется младшими битами вперед со сдвигом вправо частичного произведения. Последовательность действий при этом методе умножения следующая:
– Содержимое аккумулятора и регистра-расширителя R1 сдвигается вправо на один бит так, что младший бит множителя, выдвигаемый из регистра R1, помещается в триггер флага C.
– Если C = 1, то множимое добавляется к содержимому аккумулятора, в противном случае никаких операций не производится.
– Декрементируется счетчик циклов R3, и если его содержимое не равно нулю, то все действия повторяются.
– Перед выходом из подпрограммы формируется окончательный результат сдвигом частичного результата на один бит вправо:
MPL: MOV R3,#8 ; загрузка счетчика циклов
CLR A ; очистка аккумулятора
CLR C ; очистка признака переноса
SHIFT: RRC A ; сдвиг аккумулятора вправо
XCH A,R1 ; обмен аккумулятора и R1
RRC A ; сдвиг множителя с занесением
; выдвигаемого бита в C
XCH A,R1 ; обмен аккумулятора и R1
JNC RESULT ; если C = 1, то суммирование
ADD A,R2 ; прибавление множимого
RESULT: DJNZ R3,SHIFT ; декремент счетчика и проверка
; окончания операции (R3 = 0)
RRC A ; сдвиг аккумулятора
XCH A,R1 ; обмен
RRC A ; сдвиг содержимого R1
XCH A,R1 ; обмен
Пример 1.9. Умножить аккумулятор на число 2 в степени X, где X – число (не более 8), хранящееся в R2. Умножение на 2 заменяется арифметическим сдвигом влево аккумулятора и расширителя R1:
MOV R1,#0 ; сброс R1
CLR С ; сброс флага переноса
LOOP: RLC A ; арифметический сдвиг влево объединенного
XCH A,R1 ; 16-битного результата в
RLC A ; регистровой паре (R1) (A)
XCH A,R1 ;
DJNZ R2,LOOP ; цикл
3.4.2. Изучение команд манипуляции флажками и передачи управления
1) Изучить организацию стека микроконтроллера ВЕ48;
2) Рассмотреть систему команд манипуляции флажками, условных и безусловных переходов, вызова подпрограмм;
3) Ознакомиться с приведенными ниже примерами программ на языке ассемблера;
4) Произвести ввод, отладку и трансляцию в объектный код этих программ;
5) Выполнить программы по шагам с просмотром результатов выполнения в регистрах и оперативной памяти.
Пример 2.1. Определить четность числа единиц в аккумуляторе. После выполнения программы аккумулятор сохранит свое значение, флаг 0 будет установлен, если число единиц в аккумуляторе было нечетно. Флаг F0 входит в состав PSW и в данном примере специфицирован пользователем для выполнения функций флага паритета.
CLR F0 ; сброс F0
MOV R7,#8 ; число повторов
LOOP: RRC A ; пересылка бита A.0 в перенос
JNC NEXT ; пропустить, если бит равен 0
CPL F0 ; подсчет паритета
NEXT: DJNZ R7,LOOP ; повторить 8 раз
Пример 2.2. Передать управление по метке LL, если переключатель банка регистров (бит PSW.4) установлен:
JBSET: MOV A,PSW ; передача PSW в аккумулятор
JB4 LL ; переход, если A.4 = 1
LL: … ;
Пример 2.3. Осуществить переход из нулевого банка памяти программ к программе с именем ROUT, расположенной в первом банке памяти программ:
SEL MB1 ; установка флага MB
JMP ROUT ; переход к программе ROUT
Пример 2.4. Множественное ветвление программы. Допустим, что результатом работы некоторой программы является число X (в пределах от 0 до 15). Необходимо организовать передачу управления 16 различным программам с именами ROUT0–ROUTF в зависимости от вычисленного значения X:
ORG 0 ; задание начального адреса программы
ANL A,0F ; сброс старшей тетрады A
; во избежание ошибки перехода
JMPP @A ; обращение к таблице векторов переходов
; таблица векторов переходов
DB ROUT0 ; начальный адрес программы ROUT0
DB ROUT1 ; начальный адрес программы ROUT1
…
…
…
DB ROUTF ; начальный адрес программы ROUTF
Преобразование чисел из одной системы счисления в другую. Перевод шестнадцатеричных чисел в двоичную систему счисления достигается представлением цифр шестнадцатеричного числа четырехразрядными двоичными числами. Например,
A7B = 1010 0111 1011
A 7 B
Перевод в десятичную систему счисления. Так как перевести числа из двоичной системы в шестнадцатеричную и обратно нетрудно, то для простоты выкладок рассмотрим перевод чисел из шестнадцатеричной системы и обратно.
В качестве примера перевода числа из шестнадцатеричной системы в десятичную систему выберем число 9A5F:
9A5F16 = (9∙163 + 10∙162 + 5∙161 + 15∙160)=(((9∙16+10)∙16+5)∙16+15) = 3951910
9 A 5 F
Здесь путем группировки членов вычисление полиномов представлено в форме так называемой схемы Горнера, обеспечивающей минимальное число выполняемых операций умножения.
Покажем действия по переводу чисел из десятичной системы счисления в шестнадцатеричную на примере преобразования десятичного числа 3951910 в шестнадцатеричную систему счисления
39519 |16
39504 2469 |16
15 2464 154.................................................................. |16
F 5 144 9
10
A
Отсюда 3951910 = 9A5F16. Таким образом, последовательно деля на 16 целую часть десятичного числа и образующиеся частные, получаем в последнем частном и остатках цифры всех разрядов шестнадцатеричного представления числа.