Код програми 2
.equ RAMEND = $25F
.equ SPL = $3e
.equ SPH = $3d
.DEF rBin1H = r3
.DEF rBin1L = r2
.DEF rBin2H = r4
.DEF rBin2L = r5
.DEF rmp = r16
.DEF ZL = r30
.DEF ZH = r31
;Ініціалізація аргументів
LDI r19, '1' ;Вхідне BCD-число
LDI r20, 'a' ;1ad6
LDI r21, 'd'
LDI r22, '6' ;
LDI r30, 18 ; налаштування Z-регістра
LDI r31, 0 ; регістри вх. числа
LDI r25, low(RAMEND ) ;Ініціалізація стека
out SPL, r25 ;
LDI r25, high(RAMEND ) ;
out SPH, r25 ;
rcall AscToBin2 ; виклик підпрограми перетворення
L1: rjmp L1 ; зациклення процесора
;****************************************************************************************************
;* "AscToBin2" – підпрограма перетворення двійково-десяткового числа в ASCII-коді
; у двобайтове двійкове число rBin1H(старший байт):rBin1L(молодший байт)
;* Вхід: Z вказує на розряд зі старшою цифрою числа, що перетворюється.
;* Вихід: Результат розміщується в регістрах r2Bin1H: r2Bin1L. Прапорець Т=0
;Якщо виникає переповнення, регістр Z вказує на першу недозволену цифру
;* Використані регістри: r2Bin1H: r2Bin1L, r2Bin2H: r2Bin2L, rmp
;* Використовує підпрограму Bin1Mul10
;*****************************************************************************************************
AscToBin2:
clr rBin1H ; Спочатку результат дорівнює нулю
clr rBin1L
clt ; Очищення прапорця Т помилки
AscToBin2a:
ld rmp,Z+ ; нe враховувати пробіли і нулі, які передують числу
cpi rmp,' ' ; поточний байт -пробіл?
breq AscToBin2a ;якщо так - на завантаження наступного символа
cpi rmp,'0' ; zero? це '0' ?
breq AscToBin2a
AscToBin2b:
subi rmp,'0' ; відняти від поточного коду ASCII-код '0'
brcs AscToBin2d ; кінець числа?
cpi rmp,10 ; перевірити символ на допустимість
brcc AscToBin2d ; це десяткова цифра ! - на вихід з п.п.
rcall Bin1Mul10 ; множення на 10
brts AscToBin2c ; переповнення - на вихід з T-прапорцем =1
add rBin1L,rmp ; додати цифру до двійкового коду
ld rmp,Z+ ; завантаження наступного символа
brcc AscToBin2b ; переповнення відсутнє MSB
inc rBin1H ; переповнення є to binary MSB
brne AscToBin2b ; переповнення відсутнє MSB
set ; встановити прапорець помилки
AscToBin2c:
sbiw ZL,1 ; назад на один символ
AscToBin2d:
ret
; Допоміжна підпрограма множення 16-бітового двійкового числа на 10
Bin1Mul10:
push rBin2H ; збереження поточних даних робочих
push rBin2L ; регістрів rBin2H: rBin2L
mov rBin2H,rBin1H ; тимчасове збереження числа Num
mov rBin2L,rBin1L ; в регістрах rBin2H: rBin2L
add rBin1L,rBin1L ; множення Num на два
adc rBin1H,rBin1H
brcs Bin1Mul10b ; якщо переповнення, вихід з підпрограми
Bin1Mul10a:
add rBin1L,rbin1L ; множення Num на два (4 * Num)
adc rBin1H,rBin1H
brcs Bin1Mul10b ; якщо переповнення, вихід з підпрограми
add rBin1L,rBin2L ; додавання Num (5* Num)
adc rBin1H,rBin2H
brcs Bin1Mul10b ; якщо переповнення, вихід з підпрограми
add rBin1L,rBin1L ; останнє множення на два (10 * Num)
adc rBin1H,rBin1H
brcc Bin1Mul10c ; якщо переповнення відсутнє, T=0
Bin1Mul10b:
set ; інакше встановити прапорець T=1
Bin1Mul10c:
pop rBin2L ; Відновлення вмісту робочих регістрів
pop rBin2H
ret
Висновок: на цій лабораторній роботі ми поглибили навички з програмування мікроконторолерів AVR (далі - МК) на мові Асемблер.