- •2. Типовые задачи программирования
- •2.1. Арифметические и логические операции
- •2.1.1. Сложить содержимое ячейки внутренней памяти oper1 и регистра r0, сумму поместить в ячейку внутренней памяти sum.
- •2.1.2. Сложить содержимое регистра r0 и регистра r1, сумму поместить в ячейку внутренней памяти sum.
- •2.1.3. Вычесть из содержимого ячейки First внешней памяти данных содержимое внутренней ячейки с адресом 35н, результат поместить во вторую ячейку внешней памяти Second.
- •2.2.1. Перейти к метке dest, если содержимое ячейки внутренней памяти с адресом oper1 меньше содержимого ячейки внутренней памяти с адресом oper2.
- •2.3.1.1.Переслать 5 байт из внутренней памяти данных во другую область этого же сегмента памяти данных. Начальный адрес 1-го байта - 20н, переслать надо в ячейки, начиная с адреса 40н.
- •2.3.1.2. Переписать все байты массива чисел во внешней памяти с начальным адресом addr1 и количеством элементов, содержащихся в r5 в другую область внешней памяти с начальным адресом addr2.
- •2.3.2. Пересылка из одной области памяти в другую
- •2.3.2.1. Переслать 5 байт из внешней памяти данных во внутреннюю. Начальный адрес 1-го байта - 0000н, переслать надо в область, начиная с адреса 20н.
- •2.3.2.2. Переслать 10 байт из внутренней памяти данных во внешнюю. Начальный адрес 1-го байта - 20н, переслать надо, начиная с адреса 2000н.
- •2.3.2.3. Переслать 10 байт из памяти команд во внешнюю память данных. Начальный адрес 1-го байта - метка array1:, переслать надо, начиная с адреса 2000н.
- •2.5. Операции подсчета
- •2.5.1. Подсчитать количество ненулевых элементов в байтовом массиве внутренней памяти, адрес начала которого содержится в r0, а количество элементов - в r3.
- •2.5.2. Подсчитать количество элементов, равных ff, в байтовом массиве внутренней памяти, адрес начала которого содержится в r1, а количество элементов - в r3.
- •2.5.3. Подсчитать количество элементов, равных ffff, в массиве двухбайтовых чисел внутренней памяти, адрес начала которого содержится в r0.
- •2.6. Работа с элементами таблицы
- •2.7. Битовые операции
- •2.7.1 Сравнить поразрядно содержимое а и величины val и установить в 1, несовпадающие разряды прочие оставить без изменения.
- •2.7.2 Инвертировать разряды 3, 5, 7 аккумулятора.
- •2.7.3. Перейти к метке dest, если разряды 4,5,6 порта p2 равны 510 (1012).
- •2.7.4. Установить разряды 2,3,4 порта p0 равными 610 (1102) с сохранением содержимого остальных разрядов. Данные находятся в а.
- •2.7.6. Перейти к метке dest, если разряд 5 порта p2 равен 0.
- •2.8. Работа с операндами увеличенной длины
- •2.8.1.Увеличить содержимое регистров r4, r5 (16-ти разрядное число) на 3 (с проверкой возможного переполнения младшего разряда 16-ти разрядного числа).
- •2.8.2. Сдвинуть вправо 16 - ти разрядное число на 1 разряд.
- •2.9.1. Заполнить числом, содержащимся в регистре r3 область внешней памяти с начальным адресом addr1 и количеством элементов, содержащихся в r4.
- •2.12. Нахождение максимума и минимума
2.7.6. Перейти к метке dest, если разряд 5 порта p2 равен 0.
NAME MASK5
Beg: jnb p2.5, DEST
END
2.8. Работа с операндами увеличенной длины
В МК MCS-51 команды 16-разрядной арифметики отсутствуют, за исключением работы с указателем данных DPTR. Поэтому для простейших операций можно использовать пересылку слова в DPTR, а для более сложных - побайтовая обработка числа. При этом надо помнить, что возможно переполнение либо старшего, либо младшего байтов, и бит переноса надо учитывать в дальнейших операциях.
2.8.1.Увеличить содержимое регистров r4, r5 (16-ти разрядное число) на 3 (с проверкой возможного переполнения младшего разряда 16-ти разрядного числа).
Распределение ресурсов: Для операции увеличения 16-разрядного числа на не очень большую цифру можно использовать операцию инкремента регистра DPTR. При этом не надо проверять перенос из младшего байта в старший, так для DPTR он происходит автоматически.
NAME INCR1
Beg: mov dph,r4 ;пересылка содержимого старшего байта числа в старший регистр DPTR
mov dpl,r5 ;пересылка содержимого младшего байта числа в младший регистр DPTR
inc dptr ;увеличение числа на 3
inc dptr ;
inc dptr ;
mov r4,dph ;обратная пересылка полученного числа в R4, R5
mov r5,dpl ;
END
2.8.2. Сдвинуть вправо 16 - ти разрядное число на 1 разряд.
Распределение ресурсов: В отличие от задачи 2.8.1. здесь придется использовать в качестве промежуточного регистра аккумулятор, так как операция сдвига осуществляется только для этого регистра. При этом необходимо проверять наличие переноса из младшего байта в старший. Пусть число располагается в регистрах R3 (старший байт), R4 (младший байт).
NAME SHIFT1
Beg: clr c ;очистка бита переноса перед операцией сдвига
mov a,r4 ;пересылка младшего байта в АСС
rrc a ;сдвиг вправо с учетом бита переноса, возможный перенос при сдвиге помещается во флажок С
mov r4,a ;обратная пересылка уже сдвинутого младшего байта
mov a,r3 ;пересылка старшего байта в АСС
rrc a ;сдвиг вправо с учетом бита переноса
mov r3,a ;обратная пересылка уже сдвинутого старшего байта
END
2.9.1. Заполнить числом, содержащимся в регистре r3 область внешней памяти с начальным адресом addr1 и количеством элементов, содержащихся в r4.
Распределение ресурсов: Операция заполнения даже проще, чем пересылка, так как не надо запоминать два адреса, а только один.
NAME FILL1
Beg: mov dptr, #ADDR1 ;загрузка в регистр-указатель адреса первой ячейки
m1: movx a, @dptr ;пересылка содержимого первой ячейки в А
mov a, r3 ;заполнение этого регистра байтом из R3
movx @dptr,a ;обратная пересылка уже заполненного байта во внешнюю память
inc dptr ;увеличение адреса на 1
djnz r4, m1 ;уменьшение счетчика числа байтов на 1, проверка его на 0, и если не 0, то зацикливание
END
2.10. Простейшие арифметические операции
В МК MCS-51 присутствуют команды умножения и деления целых чисел. Однако можно и не использовать их в простейших случаях, а применять либо сложение, либо сдвиг.
2.10.1. Умножить содержимое А на 4, не используя операцию умножения МК.
Распределение ресурсов: В данном конкретном случае можно воспользоваться тем свойством, что умножение числа на величину, которая кратна степени двойки, равнозначно сдвигу числа влево на количество разрядов, которое равно этой степени.
NAME MUL1
Beg: rl a ;сдвиг числа влево, что равнозначно умножению на 2
rl a ;сдвиг числа влево, что равнозначно умножению на 2
END
2.10.2. Разделить содержимое А на 2, не используя операцию деления МК
Распределение ресурсов: Здесь, подобно задаче 2.10.1., можно воспользоваться тем свойством, что деление числа на величину, которая кратна степени двойки, равнозначно сдвигу числа вправо на количество разрядов, которое равно этой степени.
NAME MUL1
Beg: rr a ;сдвиг числа вправо, что равнозначно делению на 2
END
2.11. Суммирование массивов
При подсчете суммы массива байтовых чисел для ее хранения отводится 2 ячейки, так как теоретически максимально возможная сумма составляет не более 65535. Подсчет осуществляется в цикле, а перед ним необходимо обнулить ячейки результата.
2.11.1. Подсчитать сумму чисел в однобайтном массиве во внутренней памяти данных. Массив начинается с ячейки BEG, количество элементов указано в R5, сумма должна быть помещена в пару ячеек с адресами SUM и SUM +1.
Распределение ресурсов: Так как теоретически сумма однобайтовых чисел может превышать 255, то для хранения суммы отводится 2 ячейки.
NAME SUM10
Beg1: mov r0, #BEG ;загрузка адреса начала массива
mov r1, #SUM ;загрузка адреса ячейки суммы
mov @r1, #0 ;обнуление младшего байта суммы
inc r1 ;увеличение адреса на 1 для указания на старший байт суммы
mov @r1, #0 ;обнуление старшего байта суммы
dec r1 ;установка указателя снова на младший байт суммы
m1: mov a, @r1 ;передача младшего байта суммы в А
add a, @r0 ;суммирование числа с младшим байтом суммы
mov @r1, a ;сохранение младшего байта суммы
inc r1 ;установка указателя на старший байт суммы
mov a, @r1 ;передача старшего байта суммы в А
addc a, #0 ;суммирование со старшим байтом суммы возможного переноса
mov @r1, a ;сохранение старшего байта суммы
dec r1 ;установка указателя снова на младший байт суммы
inc r0 ;увеличение указателя на число на 1
djnz r5, m1 ;уменьшение счетчика числа байтов на 1, проверка на 0 и зацикливание, если не 0
END