Вс апр 10, 2022 19:37:22
Пн апр 11, 2022 12:04:05
Пн апр 11, 2022 21:02:32
Вт апр 12, 2022 12:34:54
;==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==
; Процедура умножает 4-байтную величину ABCD на N-байтную T...T
; Исходные ресурсы:
; - r16 - r19 - первый сомножитель (ABCD)
; - r20 - количество N байт 2-го сомножителя
; - X:(X+N-1) - второй сомножитель (в ОЗУ)
; - X - указатель на второй сомножитель в ОЗУ и буфер результата
; Возвращаемый результат:
; - r12 - r15 - старшие 4 байта произведения
; - (X+N):(X+2N-1)
; - младшие N байт произведения (в ОЗУ)
; Используемые ресурсы:
; - zero - глобальный (для всей программы) регистр с нулевым значением
; - r4 - r11 - квадраты байтов первого сомножителя
; - r21 - очередной байт 2-го сомножителя
; - r22, r23 - подгружаемые квадраты разностей и байтов 2-го сомножителя
; - r24 - рабочий регистр
; - r25 - счётчик итераций цикла
; - Z - указатель на таблицу квадратов в ПЗУ
; - STACK - 1 байт стека
; Размер процедуры 226 байт (113 инструкций)
; Время выполнения 113 * N + 50 циклов (включая rcall и ret)
;--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--
mul_32x8N: ; Подгрузка из ПЗУ квадратов байтов первого сомножителя
ldi ZH, HIGH(2*SquareTable1)
mov ZL, r16 ; Байт D
lpm r5, Z ; Старший байт D^2
ldi ZH, HIGH(2*SquareTable0)
lpm r4, Z ; Младший байт D^2
mov ZL, r17 ; Байт C
lpm r6, Z ; Младший байт C^2
ldi ZH, HIGH(2*SquareTable1)
lpm r7, Z ; Старший байт C^2
mov ZL, r18 ; Байт B
lpm r9, Z ; Старший байт B^2
ldi ZH, HIGH(2*SquareTable0)
lpm r8, Z ; Младший байт B^2
mov ZL, r19 ; Байт A
lpm r10, Z ; Младший байт A^2
ldi ZH, HIGH(2*SquareTable1)
lpm r11, Z ; Старший байт A^2
; Инициализация вспомогательных данных
clr r12 ; Инициализация рабочих регистров
clr r13
clr r14
clr r15
clr r24
mov r25, r20 ; Счётчик итераций
mul_32x8N_1: ; Основной цикл процедуры
ld r21, X ; Очередной байт T второго сомножителя
; Расчёт модулей первых двух разностей
mov ZL, r18 ; Байт B
sub ZL, r21 ; Разность B - T
brcc mul_32x8N_2
neg ZL ; Модуль разности |B - T|
mul_32x8N_2: push ZL ; Сохранение |B - T| в стек
mov ZL, r16 ; Байт D
sub ZL, r21 ; Разность D - T
brcc mul_32x8N_3
neg ZL ; Модуль разности |D - T|
mul_32x8N_3: ; Прогрузка и вычитание из результата квадратов первых двух разностей
lpm r23, Z ; Старший байт (D - T)^2
ldi ZH, HIGH(2*SquareTable0)
lpm r22, Z ; Младший байт (D - T)^2
sub r12, r22
sbc r13, r23
pop ZL ; Извлечение |B - T| из стека
lpm r22, Z ; Младший байт (B - T)^2
ldi ZH, HIGH(2*SquareTable1)
lpm r23, Z ; Старший байт (B - T)^2
sbc r14, r22
sbc r15, r23
sbc r24, zero ; Заём
; Добавление квадратов байтов первого сомножителя
add r12, r4 ; Младший байт D^2
adc r13, r5 ; Старший байт D^2
adc r14, r8 ; Младший байт B^2
adc r15, r9 ; Старший байт B^2
adc r24, zero ; Перенос
; Подгрузка квадрата байта T второго сомножителя
mov ZL, r21 ; Байт T
ldi ZH, HIGH(2*SquareTable0)
lpm r22, Z ; Младший байт T^2
ldi ZH, HIGH(2*SquareTable1)
lpm r23, Z ; Старший байт T^2
; Добавление квадрата байта T второго сомножителя
add r12, r22 ; Младший байт T^2
adc r13, r23 ; Старший байт T^2
adc r14, r22 ; Младший байт T^2
adc r15, r23 ; Старший байт T^2
adc r24, zero ; Перенос
; Сдвиг разрядов на один байт с сохранением одного байта произведения
add XL, r20 ; Сохранение в ОЗУ очередного байта
st X+, r12 ; произведения и перевод указателя
sub XL, r20 ; на следующий байт 2-го множителя
mov r12, r13
mov r13, r14
mov r14, r15
mov r15, r24
clr r24 ; Инициализация старшего рабочего байта
; Добавление квадрата байта T второго сомножителя
add r12, r22
adc r13, r23
adc r14, r22
adc r15, r23
adc r24, zero ; Перенос
; Добавление квадратов байтов первого сомножителя
add r12, r6 ; Младший байт C^2
adc r13, r7 ; Старший байт C^2
adc r14, r10 ; Младший байт A^2
adc r15, r11 ; Старший байт A^2
adc r24, zero ; Перенос
; Расчёт модулей вторых двух разностей
sub ZL, r19 ; Разность T - A
brcc mul_32x8N_4
neg ZL ; Модуль разности |A - T|
mul_32x8N_4: push ZL ; Сохранение |A - T| в стек
mov ZL, r17 ; Байт C
sub ZL, r21 ; Разность C - T
brcc mul_32x8N_5
neg ZL ; Модуль разности |C - T|
mul_32x8N_5: ; Прогрузка и вычитание из результата квадратов вторых двух разностей
lpm r23, Z ; Старший байт (C - T)^2
ldi ZH, HIGH(2*SquareTable0)
lpm r22, Z ; Младший байт (C - T)^2
sub r12, r22
sbc r13, r23
pop ZL ; Извлечение |A - T| из стека
lpm r22, Z ; Младший байт (A - T)^2
ldi ZH, HIGH(2*SquareTable1)
lpm r23, Z ; Старший байт (A - T)^2
sbc r14, r22
sbc r15, r23
sbc r24, zero ; Заём
; Декремент счётчика циклов и переход к следующей итерации
dec r25
breq mul_32x8N_6
rjmp mul_32x8N_1
mul_32x8N_6: ; Деление результата на 2 для формирования искомого произведения
add XL, r20 ; Указатель -- за N-й байт результата в ОЗУ
lsr r24 ; Деление на 2 старших 4-х байт результата
ror r15
ror r14
ror r13
ror r12
mul_32x8N_7: ; Деление младших N байт в ОЗУ на 2
ld r24, -X ; Сдвиг указателя и чтение очередного байта
ror r24 ; Деление на 2
st X, r24 ; Сохранение байта на место
dec r20 ; Декремент счётчика байтов
brne mul_32x8N_7
ret
;==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==
Вт апр 12, 2022 15:24:14
Ср апр 13, 2022 10:39:59
;==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==
; Процедура перемножает две 4-байтные величины
; Исходные ресурсы:
; - r16 - r19 - первый сомножитель (затирается в процессе работы)
; - r20 - r23 - второй сомножитель
; Возвращаемый результат:
; - r12 - r15 - Старшие 4 байта произведения
; - r16 - r19 - Младшие 4 байта произведения
; Используемые ресурсы:
; - r24 - счётчик итераций
; Размер процедуры 50 байт (25 инструкций)
; Время выполнения 431 + 3 * Sb циклов (максимум 527 циклов, включая rcall и ret),
; где Sb -- число единичных бит первого сомножителя
;--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--
mul_32x32: clr r12
clr r13
clr r14
clr r15
ldi r24, 0x20
lsr r19
ror r18
ror r17
ror r16
mul_32x32_1: ; Основной цикл процедуры
brcc mul_32x32_2
add r12, r20
adc r13, r21
adc r14, r22
adc r15, r23
mul_32x32_2: ror r15
ror r14
ror r13
ror r12
ror r19
ror r18
ror r17
ror r16
dec r24
brne mul_32x32_1
ret
;==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==
;==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==
; Процедура перемножает две 3-байтные величины
; Исходные ресурсы:
; - r16 - r18 - первый сомножитель (затирается в процессе работы)
; - r19 - r21 - второй сомножитель
; Возвращаемый результат:
; - r13 - r15 - Старшие 3 байта произведения
; - r16 - r18 - Младшие 3 байта произведения
; Используемые ресурсы:
; - r22 - счётчик итераций
; Размер процедуры 40 байт (20 инструкций)
; Время выполнения 277 + 2 * Sb циклов (максимум 325 циклов, включая rcall и ret),
; где Sb -- число единичных бит первого сомножителя
;--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--
mul_24x24: ; Подготовка старших байт результата и счётчика итераций
clr r13
clr r14
clr r15
ldi r22, 0x18
lsr r18
ror r17
ror r16
mul_24x24_1: ; Основной цикл процедуры
brcc mul_24x24_2
add r13, r19
adc r14, r20
adc r15, r21
mul_24x24_2: ror r15
ror r14
ror r13
ror r18
ror r17
ror r16
dec r22
brne mul_24x24_1
ret
;==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==
Ср апр 13, 2022 15:57:18
Считает авр-студия. А умножение неоптимальное от слова совсем. Это была первая попытка сделать программу для AT90S2313 где-то в 1999м.B@R5uk писал(а):Что-то мне кажется вы не правильно посчитали время работы. Ну не может быть так медленно, даже если код не самый оптимальный.
Ср апр 13, 2022 20:37:27
Вт май 03, 2022 05:49:17
Вт май 03, 2022 09:53:43
Вт май 03, 2022 14:13:52
Вт май 03, 2022 17:55:28
Вт май 03, 2022 18:17:49
Вт май 03, 2022 21:04:25
Ср май 04, 2022 02:34:04
Ср май 04, 2022 06:57:07
Ср май 04, 2022 16:21:46
Ср май 04, 2022 16:34:35
Ср май 04, 2022 16:49:51
Ср май 04, 2022 17:46:54
сколько можно повторять - не за один такт ,а за один ЦИКЛ!!!Demiurg писал(а):как разработчики МК добились выполнения большинства команд за один такт.