Advertisement
Guest User

Untitled

a guest
Apr 24th, 2019
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.83 KB | None | 0 0
  1. .equ ARR_PTR = $0180;адрес начала
  2. .equ LSR_K = $05;количество сдвигов
  3. .def PARAM1 = R22
  4. .def PARAM2 = R23
  5. .def PARAM3 = R24
  6. .def PARAM4 = R25
  7.  
  8. ;====================================================================
  9.  
  10. ;====================================================================
  11. ; VARIABLES
  12. ;====================================================================
  13.  
  14. ;====================================================================
  15. ; RESET and INTERRUPT VECTORS
  16. ;====================================================================
  17.  
  18. ; Reset Vector
  19. rjmp Start
  20.  
  21. ;====================================================================
  22. ; CODE SEGMENT
  23. ;формат чисел при переносе в ОЗУ ;llhh, ll - младшие байты, hh - старшие байты
  24.  
  25.  
  26. .org $40
  27. ARRAY: .dw $0A,$0101,$0101,$0101,$0101,$0101
  28. LOAD_RAM_DATA: ;подпрограмма загрузки массива в ОЗУ
  29. push XL
  30. push XH
  31. push ZL
  32. push ZH
  33. push R16;тут размр числа будет
  34. push R17 ;сохранение состояний регистров в стек
  35. ;X используется для хранения адреса записи в ОЗУ
  36. ;Z используется для хранения адреса чтения из памяти команд
  37. clr R17
  38. mov ZL, PARAM1 ;запись младшего байта адреса массива, находящегося на метке ARRAY
  39. mov ZH, PARAM2 ;запись старшего байта адреса массива ARRAY, находящегося на метке ARRAY
  40. mov XL, PARAM3 ;запись адреса начала массива в ОЗУ
  41. mov XH, PARAM4
  42. lpm R16, Z+ ;запись в R16 нулевого элемента массива, содержащего его размер и находящегося по адрессу из Z
  43. st X+, R16 ;запись количества элементов массива по адресу для его записи в ОЗУ
  44. adiw Z, 1 ;сложение слова с константой для того, чтобы адрес в Z указывал на первый элемент массива
  45.  
  46. LOAD_TO_RAM: ;цикл загрузки значений массива из памяти команд в ОЗУ
  47. lpm R17, Z+ ;запись в R17 адреса из Z
  48. st X+, R17 ;запись значения из адреса R17 по адресу Х с постинкрементом адреса ОЗУ
  49. dec R16
  50. brne LOAD_TO_RAM ;пока значение в R16 не равно 0, переход по метке
  51. pop R17
  52. pop R16
  53. pop ZH
  54. pop ZL
  55. pop XH
  56. pop XL ;выгрузка состояний регистров из стека
  57. ret
  58.  
  59. LEFT_SHIFT:
  60. push YL
  61. push YH
  62. push XL
  63. push XH
  64. push R16
  65. push R17
  66. push R18
  67. push R19
  68.  
  69. clr R17
  70. clr PARAM4
  71. mov YL, PARAM1
  72. mov YH, PARAM2
  73. mov XL, PARAM1
  74. mov XH, PARAM2
  75. adiw XL, 1;сдвигаем на 1 потому что первое - длина массива
  76. ld R16, Y+ ;запись значения размера массива в R16 по адресу Y
  77. tst R16 ;проверка размера массива на 0
  78. brne CHECK_BITS ;переход по метке к пересылке массива
  79. rjmp RETURN_SHIFT ;переход к завершению подпрограммв без пересылки из за пустоты исходного массива
  80. CHECK_BITS:
  81. ld R17, Y
  82. clr R18
  83. clr R19
  84. sbrs R17,7;проверяем бит знака
  85. inc R18
  86. sbrs R17,6;проверяем бит старшего числа
  87. inc R19
  88. cpse R18, R19
  89. rjmp OVERFLOW;если равны то устанавливаем флаг переполнения
  90. GOTO_END:;прибавление к каждой регистровой паре по количеству элементов.После x и y указывают на пару в конце массива
  91. clr R18
  92. add YL, R16
  93. adc YH, R18
  94. add XL, R16
  95. adc XH, R18
  96. clc
  97. SHIFT:;загрузили, сдвинули, записали, вычли из количества байтов массива, если не ноль то дальше следующее число двигаем
  98. ld R17, -Y;тк адресация преинкрементная
  99. rol R17;сдвиг влево
  100. st -X, R17
  101. dec R16
  102. brne SHIFT
  103. rjmp RETURN_SHIFT
  104. OVERFLOW:
  105. inc PARAM4
  106. RETURN_SHIFT:
  107. pop R19
  108. pop R18
  109. pop R17
  110. pop R16
  111. pop XH
  112. pop XL
  113. pop YH
  114. pop YL
  115. ret
  116.  
  117. SHIFT_ARRAY:
  118. push R20
  119. mov R20, PARAM3;заносим количество сдвигов
  120. tst PARAM3
  121. brne SHIFT_ARRAY_LOOP;если можно сдвигать - сдвигаем
  122. rjmp SHIFT_ARRAY_RET
  123. SHIFT_ARRAY_LOOP:
  124. rcall LEFT_SHIFT
  125. brvs SHIFT_ARRAY_RET;пока не будет арифмтического переполнения флаг переполнения пока установлен не будет
  126. dec R20
  127. brne SHIFT_ARRAY_LOOP;пока колиество сдвигов не равно 0
  128. SHIFT_ARRAY_RET:
  129.  
  130. pop R20
  131. ret
  132.  
  133. ;====================================================================
  134.  
  135. Start:
  136. ; Write your code here
  137. ldi R16, low(RAMEND) ;запись младшего байта адреса конца ОЗУ
  138. out SPL, R16 ;загрузка значения из R16 в младший регистр пары SPL,SPH регистра указателя стека SP
  139. ldi R16, high(RAMEND) ;запись старшего байта адреса конца ОЗУ
  140. out SPH, R16 ;загрузка значения из R16 в старший регистр пары SPL,SPH регистра указателя стека SP
  141. ;первые 4 команды - инициализация стека
  142.  
  143. ldi PARAM1, low(ARRAY << 1);тк памяти программ адрес указывает не на 8 бит, а на 16
  144. ldi PARAM2, high(ARRAY << 1)
  145. ldi PARAM3, low(ARR_PTR)
  146. ldi PARAM4, high(ARR_PTR)
  147. rcall LOAD_RAM_DATA ;вызов подпрограммы загрузки массива из памяти команд в ОЗУ
  148.  
  149. ldi PARAM1, low(ARR_PTR) ;запись младшего байта значения адреса начала исходного массива
  150. ldi PARAM2, high(ARR_PTR) ;запись старшего байта адреса начала исходного массива
  151. ldi PARAM3, LSR_K ;запись байта значения К сдвигов массив
  152. rcall SHIFT_ARRAY ;вызов подпрограммы сдвига массива
  153. Loop:
  154. rjmp Loop
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement