ЗАНЯТТЯ № 2
Написання простих програм на мові асемблер
для мікроконтролера AT90S2313
1. Написати підпрограму додавання вмісту двох 8-розрядних комірок SRAM, що знаходяться за адресами Addr_1 = 90Н, Addr_2 = 91Н. Якщо результат не рівний нулю, помістити його в комірку пам’яті SRAM з адресою Addr_1, в протилежному випадку вивести результат в порт B.
; Заголовочний файл
.include <2313def.inc>
; Адреса першого числа
.equ Addr_1 = 0x90
; Адреса другого числа
.equ Addr_2 = 0x91
; Початок сегменту коду
.cseg
; Початкова адреса
.org 0
; Вектор скиду
RESET:
ldi r16, 0xDF
out SPL, r16 ; Ініціалізація стеку
rcall PP_1 ; Виклик підпрограми додавання
Wait:
rjmp Wait ; Вічний цикл
PP_1: ; Початок підпрограми додавання
lds r0, Addr_1 ; Завантажити в регістр r0 перше число
lds r1, Addr_2 ; Завантажити в регістр r1 друге число
add r0, r1 ; Додати два числа, результат занести в r0
breq L1 ; Якщо результат = 0, перейти на мітку L1
sts Addr_1, r0 ; Інакше зберегти результат за адресою Addr_1
rjmp L2 ; Перейти на мітку L2
L1: out PORTB, r0 ; Вивести результат в порт В
L2:
ret ; Повернення з підпрограми
2. Написати підпрограму переводу безнакового цілого числа розташованого в комірці пам’яті SRAM з адресою Addr = 80Н, в двійково-десятковий код. Результат розташувати в регістрах загального призначення.
; Заголовичний файл
.include <2313def.inc>
; Адреса числа, яке потрібно перевести в двійково-десятковий код
.equ Addr = 0x80
; Робочі регістри
.def temp1 = r16
.def temp2 = r17
; Регістри сотень, десятків та одиниць
.def LCD_100 = r20
.def LCD_10 = r21
.def LCD_1 = r22
; Сегмент коду
.cseg
; Початкова адреса 0
.org 0
; Вектор скиду
RESET:
ldi temp1, RAMEND ; RAMEND = 0xDF (див. файл 2313def.inc)
out SPL, temp1 ; Ініціалізація стеку
ldi temp1, 125 ; Нехай потрібно перевести число 125
sts Addr, temp1 ; Зберегти 125 за адресою Addr
rcall Bin_to_Dec ; Виклик підпрограми переводу
Wait:
rjmp Wait ; Вічний цикл
Bin_to_Dec:
lds temp1, Addr ; Занести число для переводу в temp1
ldi LCD_100, -1 ; Присвоїти LCD_100 = -1
B2: inc LCD_100 ; LCD_100 = LCD_100 + 1
subi temp1, 100 ; temp1 = temp1 - 100
brsh B2 ; Якщо temp1 >= 0 перейти на В2
ldi LCD_10, 100 ; Відновити temp1
add temp1, LCD_10 ; temp1 = temp1 + 100
ldi LCD_10, -1 ; Присвоїти LCD_10 = -1
B3: inc LCD_10 ; LCD_10 = LCD_10 + 1
subi temp1, 10 ; temp1 = temp1 - 10
brsh B3 ; Якщо temp1 >= 0 перейти на В3
ldi temp2, 10 ; Відновити temp1
add temp1, temp2 ; temp1 = temp1 + 10
mov LCD_1, temp1 ; Занести в LCD_1 кількість одиниць
ret ; Повернення з підпрограми
3. Написати підпрограму переводу двійково-десяткового числа розташованого в комірці пам’яті SRAM з адресою Addr = С0Н в двійковий код. Результат розташувати в регістрі загального призначення.
; Заголовочний файл
.include <2313def.inc>
; Адреса числа, яке потрібно перевести в двійковий код
.equ Addr = 0xC0
; Робочі регістри
.def temp1 = r16
.def temp2 = r17
; Регістр результату
.def result = r18
; Сегмент коду
.cseg
; Початкова адреса
.org 0
; Вектор скиду
RESET:
ldi temp1, RAMEND
out SPL, temp1 ; Ініціалізація стеку
ldi temp1, 0b01010111
sts Addr, temp1 ; Занести в Addr число 57 (2-10)
rcall BCD_BIN ; Виклик підпрограми переводу 2-10->2
Wait:
rjmp Wait ; Вічний цикл
; Підпрограма переводу з 2-10 коду в двійковий
BCD_BIN:
ldi result, 0 ; Обнулити регістр результату (result = 0)
lds temp1, Addr ; Завантажити в temp1 вміст Addr (temp1 = 0b01010111)
mov result, temp1 ; Переслати 0b01010111 в result
andi result, 0b00001111 ; Виділити одиниці: result = 0b00000111
swap temp1 ; Поміняти місцями тетради: temp1 = 0b01110101
andi temp1, 0b00001111 ; Виділити десятки: result = 0b00000101
ldi temp2, 10 ; temp2 = 10
L1:
subi temp1, 1 ; temp1 = temp - 1
brlo L2 ; Якщо temp1 < 0 перейти на L2
add result, temp2 ; Інакше result = result + 10
rjmp L1 ; Перейти на початок циклу L1
L2: ret ; Повернення з підпрограми
4. Написати підпрограму формування часової затримки тривалістю 3 с. Тактова частота мікроконтролера 8 МГц.
Підпрограма часової затримки будується так:
А. Розраховується кількість тактів EMBED Equation.3 необхідна для формування заданого часового інтервалу EMBED Equation.3 при тактовій частоті EMBED Equation.3 :
EMBED Equation.3 .
Б. Складаємо рівняння з врахуванням того, що команда виклику підпрограми EMBED Equation.3 виконується за 3 такти, повернення з підпрограми EMBED Equation.3 – 4 такти, завантаження регістрів лічби EMBED Equation.3 – 1 такт (всього 3 команди), а тіло циклу виконується EMBED Equation.3 раз і складається з 5 тактів: EMBED Equation.3 – 1 такт, EMBED Equation.3 – 1 такт (2 команди), EMBED Equation.3 – 2 такти (за винятком одного разу коли здійснюється вихід з циклу – тоді 1 такт). Отже будемо мати
EMBED Equation.3
В. Для того щоб рівняння мало цілий розв’язок необхідно в п/п затримки додати одну холосту команду EMBED Equation.3 (no operation) тривалістю 1 такт. Тоді наше рівняння запишеться:
EMBED Equation.3
Таким чином в циклі, який починається міткою Delay відбувається віднімання від числа EMBED Equation.3 , розташованого в регістрах Delay1-Delay3 одиниці, поки воно не стане менше 0, після чого здійснюється вихід з циклу. Ознакою того, що число стало менше 0, є встановлення прапорця позики С в регістрі стану SREG (перевіряється командою EMBED Equation.3 ).
; Заголовочний файл
.include <2313def.inc>
; Константа часової затримки: 4 + 3 + 3 + 5*(N + 1) - 1 + 1 = FCLK*T
.equ T_3sec = (24000000 - 15)/5 ; 3 секунди
; Робочий регістр
.def temp = r16
; Регістри затримки
.def Delay1 = r17
.def Delay2 = r18
.def Delay3 = r19
; Сегмент коду
.cseg
; Початкова адреса
.org 0
; Вектор скиду
RESET:
ldi temp, RAMEND
out SPL, temp ; Ініціалізація стеку
ldi Delay1, low(T_3sec) ; Занести в Delay1 1-й байт T_3sec
ldi Delay2, high(T_3sec) ; Занести в Delay2 2-й байт T_3sec
ldi Delay3, byte3(T_3sec) ; Занести в Delay3 3-й байт T_3sec
rcall Delay ; Виклик підпрограми затримки
Wait:
rjmp Wait ; Вічний цикл
Delay:
;Підпрограма часової затримки
subi Delay1, 1 ; Відняти від T_3sec
sbci Delay2, 0
sbci Delay3, 0
brcc Delay ; Якщо результат >= 0 перейти на Delay
nop ; Холоста команда
ret ; Повернення з підпрограми
5. Написати підпрограму додавання двох масивів з адресами Array1 та Array2, розміром 10 байт. Результат додавання записати на місце першого масиву.
; Заголовочний файл
.include <2313def.inc>
; Константа - розмір масиву
.equ Array_Size = 10
; Лічильник
.def Count = r16
; Робочі регістри
.def temp1 = r17
.def temp2 = r18
; Сегмент коду
.cseg
; Початкова адреса
.org 0
; Вектор скиду
RESET:
ldi temp1, RAMEND
out SPL, temp1 ; Ініціалізація стеку
ldi XL, low(Array1) ; Занести в індексний рег. Х адресу
ldi XH, high(Array1) ; першого масиву
ldi YL, low(Array2) ; Занести в індексний рег. Y адресу
ldi YH, high(Array2) ; другого масиву
ldi Count, Array_Size ; Занести в лічильник розмір масиву
rcall Array_Sum ; Виклик підпрограми додавання масивів
Wait:
rjmp Wait ; Вічний цикл
Array_Sum:
ld temp1, X ; Занести в temp1 елемент масиву Array1
ld temp2, Y+ ; Занести в temp2 елемент масиву Array2
add temp1, temp2 ; Додати два елементи
st X+, temp1 ; Зберегти суму в масиві Array1
dec Count ; Зменшити лічильник на 1
brne Array_Sum ; Поки Count не 0, перейти на Array_Sum
.dseg
Array1: .byte 10 ; Резервування пам'яті для масиву Array1
Array2: .byte 10 ; Резервування пам'яті для масиву Array1
6. Написати підпрограму знаходження максимального числа у масиві 8-розрядних беззнакових чисел в SRAM з адресою Array, розміром 10 байт. Максимальне число запам’ятати в комірці SRAM з адресою uMax, його адресу в комірках Max_Addr і Max_Addr + 1.
; Заголовочний файл
.include <2313def.inc>
; Константа - розмір масиву
.equ Array_Size = 10
; Лічильник
.def Count = r16
; Робочі регістри
.def temp1 = r17
.def temp2 = r18
; Сегмент коду
.cseg
; Початкова адреса
.org 0
; Вектор скиду
RESET:
ldi temp1, RAMEND
out SPL, temp1 ; Ініціалізація стеку
ldi XL, low(Array) ; Занести в індексний рег. Х
ldi XH, high(Array) ; адресу масиву Array
; Ініціалізація масиву для тестування підпрограми
ldi temp1, 3
st X+, temp1
ldi temp1, 5
st X+, temp1
ldi temp1, 7
st X+, temp1
ldi temp1, 8
st X+, temp1
ldi temp1, 129
st X+, temp1
ldi temp1, 200
st X+, temp1
ldi temp1, 220
st X+, temp1
ldi temp1, 110
st X+, temp1
ldi temp1, 77
st X+, temp1
ldi temp1, 34
st X+, temp1
ldi XL, low(Array) ; Занести в індексний рег. Х
ldi XH, high(Array) ; адресу масиву Array
ldi Count, Array_Size - 1 ; Занести в Count число 9
rcall Array_uMax ; Виклик підпрограми пошуку максимуму
Wait:
rjmp Wait ; Вічний цикл
Array_uMax:
ld temp1, X+ ; Занести перший елемент масиву в temp1
Loop:
ld temp2, X ; Занести наступний елемент масиву в temp2
cp temp2, temp1 ; Порівняти: temp2 - temp1
brlo L1 ; Якщо temp2 < temp1 перейти на L1
mov temp1, temp2 ; Інакше занести в temp1 значення temp2
sts Max_Addr, XL ; Зберегти адресу temp2
sts Max_Addr+1, XH ; в комірках Max_Addr, Max_Addr+1
L1:
adiw XL, 1 ; Вказати на наступний елемент
dec Count ; Зменшити Count на 1
brne Loop ; Якщо Count не нуль, перейти на Loop
sts uMax, temp1 ; Зберегти масимальне значення в uMax
ret ; Повернення з підпрограми
; Сегмент даних
.dseg
Array: .byte 10 ; Виділення пам'яті для масиву
uMax: .byte 1 ; Комірка для зберігання макс. значення
Max_Addr: .byte 2 ; Адреса максимального значення
7. Написати підпрограму знаходження максимального числа у масиві 8-розрядних знакових чисел в SRAM з адресою Array, розміром 10 байт. Максимальне число запам’ятати в комірці SRAM з адресою sMax, його адресу в комірках Max_Addr і Max_Addr + 1.
; Заголовочний файл
.include <2313def.inc>
; Константа - розмір масиву
.equ Array_Size = 10
; Лічильник
.def Count = r16
; Робочі регістри
.def temp1 = r17
.def temp2 = r18
; Сегмент коду
.cseg
; Початкова адреса
.org 0
; Вектор скиду
RESET:
ldi temp1, RAMEND
out SPL, temp1 ; Ініціалізація стеку
ldi XL, low(Array) ; Занести в індексний рег. Х
ldi XH, high(Array) ; адресу масиву Array
; Ініціалізація масиву для тестування підпрограми
ldi temp1, 3
st X+, temp1
ldi temp1, 5
st X+, temp1
ldi temp1, 7
st X+, temp1
ldi temp1, 8
st X+, temp1
ldi temp1, 129
st X+, temp1
ldi temp1, 200
st X+, temp1
ldi temp1, 220
st X+, temp1
ldi temp1, 110
st X+, temp1
ldi temp1, 77
st X+, temp1
ldi temp1, 34
st X+, temp1
ldi XL, low(Array) ; Занести в індексний рег. Х
ldi XH, high(Array) ; адресу масиву Array
ldi Count, Array_Size - 1 ; Занести в Count число 9
rcall Array_sMax ; Виклик підпрограми пошуку максимуму
Wait:
rjmp Wait ; Вічний цикл
Array_sMax:
ld temp1, X+ ; Занести перший елемент масиву в temp1
Loop:
ld temp2, X ; Занести наступний елемент масиву в temp2
cp temp2, temp1 ; Порівняти: temp2 - temp1
brlt L1 ; Якщо temp2 < temp1 перейти на L1
mov temp1, temp2 ; Інакше занести в temp1 значення temp2
sts Max_Addr, XL ; Зберегти адресу temp2
sts Max_Addr+1, XH ; в комірках Max_Addr, Max_Addr+1
L1:
adiw XL, 1 ; Вказати на наступний елемент
dec Count ; Зменшити Count на 1
brne Loop ; Якщо Count не нуль, перейти на Loop
sts sMax, temp1 ; Зберегти масимальне значення в sMax
ret ; Повернення з підпрограми
; Сегмент даних
.dseg
Array: .byte 10 ; Виділення пам'яті для масиву
sMax: .byte 1 ; Комірка для зберігання макс. значення
Max_Addr: .byte 2 ; Адреса максимального значення
8. Написати п/п кодування циклічним кодом з твірним поліномом EMBED Equation.3 3-розрядної інформаційної послідовності. Продемонструвати роботу п/п для інформаційної послідовності 110.
Побудуємо твірну матрицю EMBED Equation.3 шляхом ділення одиниці з 5 нулями на твірний поліном:
EMBED Equation.3
Твірна матриця:
EMBED Equation.3
Контрольні розряди згідно твірної матриці:
EMBED Equation.3
Закодована комбінація має бути: EMBED Equation.3
; Заголовочний файл
.include <2313def.inc>
; Закодована комбінація
.def CRC = r16
; Робочі регістри
.def temp1 = r17
; Сегмент коду
.cseg
; Початкова адреса
.org 0
; Вектор скиду
RESET:
ldi temp1, RAMEND
out SPL, temp1 ; Ініціалізація стеку
ldi CRC, 0b00000110 ; Занести в рег. CRC дані для кодування
rcall CRC_Calc ; Виклик підпрограми кодування циклічним кодом
Wait:
rjmp Wait ; Вічний цикл
CRC_Calc:
ldi ZL, low(CRC_Table*2) ; Занести в інд. рег. Z адресу
ldi ZH, high(CRC_Table*2) ; таблиці CRC_Table в Flash-пам'яті програм
lsl CRC ; Звільнити молодші 3 біти
lsl CRC ; для контрольних розрядів
lsl CRC ; CRC=0 0 0 I3 I2 I1 K3 K2 K1
mov temp1, CRC ; Занести в temp1 вміст CRC
andi temp1, 0b00001000 ; Виділити біт I1
breq L1 ; Якщо I1 = 0 перейти на L1
lpm ; Інакше прочитати залишок з CRC_Table в r0
eor CRC, r0 ; Додати залишок до CRC
L1: adiw Z, 1 ; Вказати на наступний залишок
mov temp1, CRC ; Занести в temp1 вміст CRC
andi temp1, 0b00010000 ; Виділити біт I2
breq L2 ; Якщо I2 = 0 перейти на L2
lpm ; Інакше прочитати залишок з CRC_Table в r0
eor CRC, r0 ; Додати залишок до CRC
L2: adiw Z, 1 ; Вказати на наступний залишок
mov temp1, CRC ; Занести в temp1 вміст CRC
andi temp1, 0b00100000 ; Виділити біт I3
breq L3 ; Якщо I3 = 0 перейти на L3
lpm ; Інакше прочитати залишок з CRC_Table в r0
eor CRC, r0 ; Додати залишок до CRC
L3: ret ; Поверення з підпрограми
; Твірна таблиця для поліному х^3 + x + 1
CRC_Table: .db 0b00000011, 0b00000110, 0b00000111
9. Написати підпрограму кодування кодом Хемінга з d = 4 байту розташованого в регістрі r16. Контрольні розряди зберегти в регістрі r17. Продемонструвати роботу п/п для інформаційної послідовності 0b01000110.
Маємо байт даних І12 І11 І10 І9 І7 І6 І5 І3 і контрольні розряди К8 К4 К2 К1 К0.
К1 = І3 EMBED Equation.3 І5 EMBED Equation.3 І7 EMBED Equation.3 І9 EMBED Equation.3 І11
К2 = І3 EMBED Equation.3 І6 EMBED Equation.3 І7 EMBED Equation.3 І10 EMBED Equation.3 І11
К4 = І5 EMBED Equation.3 І6 EMBED Equation.3 І7 EMBED Equation.3 І12
К8 = І9 EMBED Equation.3 І10 EMBED Equation.3 І11 EMBED Equation.3 І12
К0 = І3 EMBED Equation.3 І5 EMBED Equation.3 І6 EMBED Equation.3 І7 EMBED Equation.3 І9 EMBED Equation.3 І10 EMBED Equation.3 І11 EMBED Equation.3 І12 EMBED Equation.3 К1 EMBED Equation.3 К2 EMBED Equation.3 К4 EMBED Equation.3 К8
Твірна таблиця для коду Хемінга С13, 8 запишеться
Отже контрольні розряди мають бути:
; Заголовочний файл
.include <2313def.inc>
; Інформаційні розряди
.def Data = r16
; Контрольні розряди
.def Control = r17
; Робочі регістри
.def temp1 = r18
.def Count = r19
; Сегмент коду
.cseg
; Початкова адреса
.org 0
; Вектор скиду
RESET:
ldi temp1, RAMEND
out SPL, temp1 ; Ініціалізація стеку
ldi Data, 0b01000110 ; Інформаційні розряди в temp1
rcall Hamming_Calc ; Виклик підпрограми кодування кодом Хемінга

Wait:
rjmp Wait ; Вічний цикл
Hamming_Calc:
ldi Control, 0 ; Обнулити контрольні розряди
ldi ZL, low(Hamming_Table*2) ; Занести в інд. регістр Z
ldi ZH, high(Hamming_Table*2) ; адресу твірної таблиці
ldi Count, 8 ; Занести в лічильник 8
mov temp1, Data ; Занести в temp1 інформаційні розряди
Loop:
lsr temp1 ; Зсунути черговий розряд в прапорець С
brcc L1 ; Якщо С = 0 перейти на L1
lpm ; Інакше прочитати контрольні розряди
eor Control, r0 ; Додати контрольні розряди за модулем 2
L1: adiw Z, 1 ; Вказати на наступний елемент Hamming_Table
dec Count ; Зменшити лічильник на 1
brne Loop ; Поки не ноль - перейти на Loop
ret ; Повернення з підпрограми
; Твірна таблиця коду Хемінга з d = 4, ni = 8
Hamming_Table: .db 0b00000111, 0b00001011, 0b00001101
.db 0b00001110, 0b00010011, 0b00010101
.db 0b00010110, 0b00011001
8. Знайти кількість і записати адреси тих елементів масиву, які рівні нулю. Масив починається з адреси Addr_1 = 70Н, кількість елементів масиву 10. Кількість нульових елементів записати в комірці Addr_2 = 90Н, адреси нульових елементів записати починаючи з комірки з адресою Addr_2 + 1.
; Заголовочний файл
.include <2313def.inc>
; Робочі регістри
.def temp1 = r16
.def temp2 = r17
.def Count = r18
.equ Array_Size = 10
; Сегмент коду
.cseg
; Початкова адреса
.org 0
; Вектор скиду
RESET:
ldi temp1, RAMEND
out SPL, temp1 ; Ініціалізація стеку
; Ініціалізація масиву
ldi XL, low(Array)
ldi XH, high(Array)
ldi temp1, 1
st X+, temp1
ldi temp1, 0
st X+, temp1
ldi temp1, 1
st X+, temp1
ldi temp1, 23
st X+, temp1
ldi temp1, 0
st X+, temp1
ldi temp1, 1
st X+, temp1
ldi temp1, 98
st X+, temp1
ldi temp1, 0
st X+, temp1
ldi temp1, 0
st X+, temp1
ldi temp1, 2
st X+, temp1
rcall Zero_Count ; Виклик підпрограми
Wait: rjmp Wait ; Вічний цикл
Zero_Count:
ldi XL, low(Array) ; Занести в індексний рег. Х
ldi XH, high(Array) ; адресу масиву Array
ldi YL, low(N_Zero + 1) ; Занести в інд. рег. Y
ldi YH, high(N_Zero + 1) ; адресу N_Zero + 1
ldi Count, Array_Size ; Задаємо розмір масиву (Count = 10)
ldi temp2, 0 ; Обнулюємо лічильник нульових елементів
Loop:
ld temp1, X ; Прочитати черговий елемент масиву
cpi temp1, 0 ; Порівняти його з нулем
brne L1 ; Якщо не нуль - перейти на мітку L1
inc temp2 ; Інакше збільшити лічильник кількість нулів на 1
st Y+, XL ; Зберегти адресу нульового елементу
st Y+, XH
L1:
adiw XL, 1 ; Вказати на наступний елемент
dec Count ; Зменшити лічильник на 1
brne Loop ; Якщо не кінець масиву - перейти на Loop
sts N_Zero, temp2 ; Зберегти кількість нульових елементів масиву
ret ; Повернення з підпрограми
; Сегмент даних
.dseg
.org 0x70
Array: .byte 10 ; Резервування масиву з 10 елементів починаючи з адреси 0х70 в SRAM
.org 0x90
N_Zero: .byte 1 ; Комірка для зберігання кількості нульових елементів
10. В залежності від значення третього біту в комірці з адресою Addr_1 = 70Н здійснити наступні дії:
Addr_1(3) = 1, тоді інвертувати біти числа, додати 45, поміняти місцями розряди (нульовий розряд має стати 7,…, сьомий – нульовим), і зберегти в комірці пам’яті з адресою 75Н.
Addr_1(3) = 0, тоді зсунути логічно на 3 розряди вправо, встановити старший розряд в 1, додати 20, і вивести і зберегти в комірці пам’яті з адресою 85Н.
; Заголовочний файл
.include <2313def.inc>
; Робочі регістри
.def temp1 = r16
.def temp2 = r17
.equ Addr_1 = 0x70
.equ Addr_2 = 0x75
.equ Addr_3 = 0x85

; Сегмент коду
.cseg
; Початкова адреса
.org 0
; Вектор скиду
RESET:
ldi temp1, RAMEND
out SPL, temp1 ; Ініціалізація стеку
rcall Func_1
Wait:
rjmp Wait ; Вічний цикл
Func_1:
lds temp1, Addr_1 ; Завантажити число в temp1
mov temp2, temp1 ; Скопіювати в temp2
andi temp1, 0b00001000 ; Виділити 3-й розряд
breq L1 ; Якщо 0 перейти на L1
com temp2 ; Інакше інвертувати розряди числа
subi temp2, -45 ; Додати 45
; Поміняти біти місцями:
bst temp2, 0 ; Скопіювати біт 0 в прапорець Т
bld temp1, 7 ; Вставити прапорець Т на місце 7-го біту
bst temp2, 1
bld temp1, 6
bst temp2, 2
bld temp1, 5
bst temp2, 3
bld temp1, 4
bst temp2, 4
bld temp1, 3
bst temp2, 5
bld temp1, 2
bst temp2, 6
bld temp1, 1
bst temp2, 7
bld temp1, 0
sts Addr_2, temp1 ; Зберегти результат за адресою Addr_2
rjmp L2 ; Перейти на мітку L2
L1:
lsr temp2 ; Зсунути на три розряди впарво
lsr temp2
lsr temp2
ori temp2, 0b10000000 ; Встановити 7-й біт в 1
subi temp2, -20 ; Додати 20
sts Addr_3, temp2 ; Зберегти результат за адресою Addr_3
L2:
ret ; Поверення з підпрограми

11. Здійснити додавання 2 24-розрядних чисел розташованих починаючи з комірки з адресою Addr_1 = 80Н – перше число, Addr_2 = 90Н – друге число. Підрахувати кількість одиниць в результаті, і якщо вона парна інвертувати розряди результату, інакше обнулити результат. Результат записати на місце першого числа.
; Заголовочний файл
.include <2313def.inc>
; Робочі регістри
.def temp1 = r16
.def temp2 = r17
; Регістри суми
.def SUM_1 = r18
.def SUM_2 = r19
.def SUM_3 = r20
.def Count = r21

; Адреси двох 24-розрядних чисел
.equ Addr_1 = 0x80
.equ Addr_2 = 0x90
; Сегмент коду
.cseg
; Початкова адреса
.org 0
; Вектор скиду
RESET:
ldi temp1, RAMEND
out SPL, temp1 ; Ініціалізація стеку
rcall Func_2 ; Виклик функції
Wait:
rjmp Wait ; Вічний цикл
Func_2:
lds temp1, Addr_1 ; Завантажити 1-й байт першого числа в temp1
lds SUM_1, Addr_2 ; Завантажити 1-й байт другого числа в SUM_1
add SUM_1, temp1 ; Додати два байти
lds temp1, Addr_1+1 ; Завантажити 2-й байт першого числа в temp1
lds SUM_2, Addr_2+1 ; Завантажити 2-й байт другого числа в SUM_2
adc SUM_2, temp1 ; Додати два байти з переносом
lds temp1, Addr_1+2 ; Завантажити 3-й байт першого числа в temp1
lds SUM_3, Addr_2+2 ; Завантажити 3-й байт другого числа в SUM_3
adc SUM_3, temp1 ; Додати два байти з переносом
ldi Count, 8 ; Підрахунок кількості одиниць в байті
ldi temp2, 0 ; Обнулити лічильник одиниць
mov temp1, SUM_1
L2:
lsl temp1 ; Зсунути старший біт в прапорець С
brcc L1 ; С == 0
inc temp2 ; Якщо ні, збільшити лічильник 1
L1: dec Count ; Всі 8 біт зсунуті?
brne L2 ; Якщо ні - перейти на L2
ldi Count, 8
mov temp1, SUM_2
L3:
lsl temp1
brcc L4
inc temp2
L4: dec Count
brne L3
ldi Count, 8
mov temp1, SUM_3
L5:
lsl temp1
brcc L6
inc temp2
L6: dec Count
brne L5
andi temp2, 0b00000001 ; Кількість одиниць парна
breq L7 ; Якщо так - перейти на L7
ldi SUM_1, 0 ; Інакше обнулити результат
mov SUM_2, SUM_1
mov SUM_3, SUM_1
rjmp L8 ; і перейти на L8
L7: com SUM_1 ; Якщо кількість 1 непарна
com SUM_2 ; Інвертувати результат
com SUM_3
L8:
sts Addr_1, SUM_1 ; Зберегти результат
sts Addr_1+1, SUM_2 ; на місці першого числа
sts Addr_1+2, SUM_3
ret ; Поверення з підпрограми
12. Додати до всіх елементів масиву менших нуля 25, зі всіх чисел більших нуля відняти 45, всі числа рівні нулю замінити на 80Н. Адреса початку масиву Addr_1 = 70Н, розмір 10 байт.
; Заголовочний файл
.include <2313def.inc>
; Робочі регістри
.def temp1 = r16
.def temp2 = r17
.def Count = r21

; Адреса масиву
.equ Addr = 0x70
; Розмір масиву
.equ Size = 10
; Сегмент коду
.cseg
; Початкова адреса
.org 0
; Вектор скиду
RESET:
ldi temp1, RAMEND
out SPL, temp1 ; Ініціалізація стеку
rcall Func_3 ; Виклик функції
Wait:
rjmp Wait ; Вічний цикл
Func_3:
ldi XL, low(Addr) ; Завантажити адресу масиву
ldi XH, high(Addr) ; в індексний рег. Х
ldi Count, 10 ; Розмір масиву
Loop:
ld temp1, X ; Зчитати елемент масиву в temp1
cpi temp1, 0 ; Порівняти з 0
breq L1 ; Якщо рівний 0 - перейти на L1
brlt L3 ; Якщо менший нуля - L3
subi temp1, 45 ; Інакше зменшити на 45
rjmp L2 ; і перейти на L2
L1: ldi temp1, 0x80 ; Якщо 0 - змінити на 0х80
rjmp L2 ; і перейти на L2
L3: subi temp1, -25 ; Якщо менше 0 - збільшити на 25
L2: st X+, temp1 ; Зберегти в масиві
dec Count ; Зменшити лічильник
brne Loop ; Якщо не нуль - перейти на Loop
ret ; Поверення з підпрограми
Завдання до практичного заняття №2
Написати п/п кодування циклічним кодом з твірним поліномом EMBED Equation.3 4-розрядної інформаційної послідовності. Продемонструвати роботу п/п для інформаційної послідовності 1001.
Написати п/п кодування циклічним кодом з твірним поліномом EMBED Equation.3 4-розрядної інформаційної послідовності. Продемонструвати роботу п/п для інформаційної послідовності 1100.
Написати п/п кодування циклічним кодом з твірним поліномом EMBED Equation.3 7-розрядної інформаційної послідовності. Продемонструвати роботу п/п для інформаційної послідовності 0001011.
Написати п/п кодування циклічним кодом з твірним поліномом EMBED Equation.3 8-розрядної інформаційної послідовності. Продемонструвати роботу п/п для інформаційної послідовності 10001001.
Написати п/п кодування циклічним кодом з твірним поліномом EMBED Equation.3 7-розрядної інформаційної послідовності. Продемонструвати роботу п/п для інформаційної послідовності 0100011.
Написати п/п декодування з виправленням одиничної помилки циклічним кодом з твірним поліномом EMBED Equation.3 4-розрядної інформаційної послідовності. Продемонструвати роботу п/п для кодової комбінації 1111010.
Написати п/п декодування з виправленням одиничної помилки циклічним кодом з твірним поліномом EMBED Equation.3 4-розрядної інформаційної послідовності. Продемонструвати роботу п/п для кодової комбінації 1001000.
Написати п/п декодування з виправленням одиничної помилки циклічним кодом з твірним поліномом EMBED Equation.3 8-розрядної інформаційної послідовності. Продемонструвати роботу п/п для кодової комбінації 100010011000.
Написати п/п декодування з виправленням одиничної помилки циклічним кодом з твірним поліномом EMBED Equation.3 7-розрядної інформаційної послідовності. Продемонструвати роботу п/п для кодової комбінації 01110110000.
Написати п/п кодування кодом Хемінга з EMBED Equation.3 5-розрядної інформаційної послідовності. Продемонструвати роботу п/п для інформаційної послідовності 10110.
Написати п/п кодування кодом Хемінга з EMBED Equation.3 6-розрядної інформаційної послідовності. Продемонструвати роботу п/п для інформаційної послідовності 101110.
Написати п/п кодування кодом Хемінга з EMBED Equation.3 7-розрядної інформаційної послідовності. Продемонструвати роботу п/п для інформаційної послідовності 1000110.
Написати п/п кодування кодом Хемінга з EMBED Equation.3 8-розрядної інформаційної послідовності. Продемонструвати роботу п/п для інформаційної послідовності 11101101.
Написати п/п декодування з виправленням одиничної помилки кодом Хемінга з EMBED Equation.3 5-розрядної інформаційної послідовності. Продемонструвати роботу п/п для кодової комбінації 100101101.
Написати п/п декодування з виправленням одиничної помилки кодом Хемінга з EMBED Equation.3 6-розрядної інформаційної послідовності. Продемонструвати роботу п/п для кодової комбінації 01111001000.
Написати п/п декодування з виправленням одиничної помилки кодом Хемінга з EMBED Equation.3 7-розрядної інформаційної послідовності. Продемонструвати роботу п/п для кодової комбінації 10110110111.
Написати п/п декодування з виправленням одиничної помилки кодом Хемінга з EMBED Equation.3 8-розрядної інформаційної послідовності. Продемонструвати роботу п/п для кодової комбінації 1000101011101.
Написати п/п обчислення функції EMBED Equation.3 табличним методом для EMBED Equation.3 з точністю 2-5.
Написати п/п обчислення функції EMBED Equation.3 табличним методом для EMBED Equation.3 з точністю 2-6.
Написати п/п переведення 8-бітного з двійкового коду в код Грея і навпаки.
Написати п/п формування часової затримки тривалістю 1 с. Тактова частота МК 4 МГц.
Написати п/п знаходження суми всіх елементів масиву, що більше 20, який починається з адреси Adres = 70H і містить 50 елементів.
Написати п/п сортування за зростанням елементів масиву, який починається з адреси Adres = 80 H і містить 25 елементів.
Написати п/п переставляння елементів масиву в зворотному напрямку, який починається з адреси Adres = 65H і містить 30 елементів.
Написати п/п знаходження суми всіх додатних елементів масиву, який починається з адреси Adres = 80 H і містить 20 елементів.
Написати п/п знаходження максимального і мінімального значення елементів масиву, який починається з адреси Adres = A0 H і містить 20 елементів.
Написати п/п шифрування повідомлення в ANSII-коді, яке знаходиться в пам’яті починаючи з адреси Adres = 70 H і містить 30 елементів, наступним шифром:
Продемонструвати на прикладі речення: Ще треті півні не співали.
Написати п/п розшифрування повідомлення, яке знаходиться в пам’яті починаючи з адреси Adres = 70 H і містить 30 елементів, наступним шифром:
Продемонструвати на прикладі: 13 24 33 25 44 11 21 34 36 66 36 15 24 35 11 15 52 62 44 36 14 36 66 13 16 42 16 43 35 62.
Написати п/п множення двох безнакових 8-бітних чисел.
Написати п/п ділення двох беззнакових 8-бітних чисел.