Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- .equ ARR_PTR = $0180;адрес начала
- .equ LSR_K = $05;количество сдвигов
- .def PARAM1 = R22
- .def PARAM2 = R23
- .def PARAM3 = R24
- .def PARAM4 = R25
- ;====================================================================
- ;====================================================================
- ; VARIABLES
- ;====================================================================
- ;====================================================================
- ; RESET and INTERRUPT VECTORS
- ;====================================================================
- ; Reset Vector
- rjmp Start
- ;====================================================================
- ; CODE SEGMENT
- ;формат чисел при переносе в ОЗУ ;llhh, ll - младшие байты, hh - старшие байты
- .org $40
- ARRAY: .dw $0A,$0101,$0101,$0101,$0101,$0101
- LOAD_RAM_DATA: ;подпрограмма загрузки массива в ОЗУ
- push XL
- push XH
- push ZL
- push ZH
- push R16;тут размр числа будет
- push R17 ;сохранение состояний регистров в стек
- ;X используется для хранения адреса записи в ОЗУ
- ;Z используется для хранения адреса чтения из памяти команд
- clr R17
- mov ZL, PARAM1 ;запись младшего байта адреса массива, находящегося на метке ARRAY
- mov ZH, PARAM2 ;запись старшего байта адреса массива ARRAY, находящегося на метке ARRAY
- mov XL, PARAM3 ;запись адреса начала массива в ОЗУ
- mov XH, PARAM4
- lpm R16, Z+ ;запись в R16 нулевого элемента массива, содержащего его размер и находящегося по адрессу из Z
- st X+, R16 ;запись количества элементов массива по адресу для его записи в ОЗУ
- adiw Z, 1 ;сложение слова с константой для того, чтобы адрес в Z указывал на первый элемент массива
- LOAD_TO_RAM: ;цикл загрузки значений массива из памяти команд в ОЗУ
- lpm R17, Z+ ;запись в R17 адреса из Z
- st X+, R17 ;запись значения из адреса R17 по адресу Х с постинкрементом адреса ОЗУ
- dec R16
- brne LOAD_TO_RAM ;пока значение в R16 не равно 0, переход по метке
- pop R17
- pop R16
- pop ZH
- pop ZL
- pop XH
- pop XL ;выгрузка состояний регистров из стека
- ret
- LEFT_SHIFT:
- push YL
- push YH
- push XL
- push XH
- push R16
- push R17
- push R18
- push R19
- clr R17
- clr PARAM4
- mov YL, PARAM1
- mov YH, PARAM2
- mov XL, PARAM1
- mov XH, PARAM2
- adiw XL, 1;сдвигаем на 1 потому что первое - длина массива
- ld R16, Y+ ;запись значения размера массива в R16 по адресу Y
- tst R16 ;проверка размера массива на 0
- brne CHECK_BITS ;переход по метке к пересылке массива
- rjmp RETURN_SHIFT ;переход к завершению подпрограммв без пересылки из за пустоты исходного массива
- CHECK_BITS:
- ld R17, Y
- clr R18
- clr R19
- sbrs R17,7;проверяем бит знака
- inc R18
- sbrs R17,6;проверяем бит старшего числа
- inc R19
- cpse R18, R19
- rjmp OVERFLOW;если равны то устанавливаем флаг переполнения
- GOTO_END:;прибавление к каждой регистровой паре по количеству элементов.После x и y указывают на пару в конце массива
- clr R18
- add YL, R16
- adc YH, R18
- add XL, R16
- adc XH, R18
- clc
- SHIFT:;загрузили, сдвинули, записали, вычли из количества байтов массива, если не ноль то дальше следующее число двигаем
- ld R17, -Y;тк адресация преинкрементная
- rol R17;сдвиг влево
- st -X, R17
- dec R16
- brne SHIFT
- rjmp RETURN_SHIFT
- OVERFLOW:
- inc PARAM4
- RETURN_SHIFT:
- pop R19
- pop R18
- pop R17
- pop R16
- pop XH
- pop XL
- pop YH
- pop YL
- ret
- SHIFT_ARRAY:
- push R20
- mov R20, PARAM3;заносим количество сдвигов
- tst PARAM3
- brne SHIFT_ARRAY_LOOP;если можно сдвигать - сдвигаем
- rjmp SHIFT_ARRAY_RET
- SHIFT_ARRAY_LOOP:
- rcall LEFT_SHIFT
- brvs SHIFT_ARRAY_RET;пока не будет арифмтического переполнения флаг переполнения пока установлен не будет
- dec R20
- brne SHIFT_ARRAY_LOOP;пока колиество сдвигов не равно 0
- SHIFT_ARRAY_RET:
- pop R20
- ret
- ;====================================================================
- Start:
- ; Write your code here
- ldi R16, low(RAMEND) ;запись младшего байта адреса конца ОЗУ
- out SPL, R16 ;загрузка значения из R16 в младший регистр пары SPL,SPH регистра указателя стека SP
- ldi R16, high(RAMEND) ;запись старшего байта адреса конца ОЗУ
- out SPH, R16 ;загрузка значения из R16 в старший регистр пары SPL,SPH регистра указателя стека SP
- ;первые 4 команды - инициализация стека
- ldi PARAM1, low(ARRAY << 1);тк памяти программ адрес указывает не на 8 бит, а на 16
- ldi PARAM2, high(ARRAY << 1)
- ldi PARAM3, low(ARR_PTR)
- ldi PARAM4, high(ARR_PTR)
- rcall LOAD_RAM_DATA ;вызов подпрограммы загрузки массива из памяти команд в ОЗУ
- ldi PARAM1, low(ARR_PTR) ;запись младшего байта значения адреса начала исходного массива
- ldi PARAM2, high(ARR_PTR) ;запись старшего байта адреса начала исходного массива
- ldi PARAM3, LSR_K ;запись байта значения К сдвигов массив
- rcall SHIFT_ARRAY ;вызов подпрограммы сдвига массива
- Loop:
- rjmp Loop
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement