ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Вторник
26 ноября
53279
AVR (09.03.2006 03:46, просмотров: 8404)
2 MDenis, Romario, ReAl и остальным участникам недавней дискуссии Занятно было почитать и послушать треск ломающихся копий. Ради забавы накидал решение распаковочной задачки Romario в двух вариантах - рекурсивном и инлайн - на Атмеловском ассемблере AVR. Компиляторы в очередной раз утерлись рукавом:
;Input	= 0:aaaaaaab 1:bbbbbbcc 2:cccccddd 3:ddddeeee 4:eeefffff 5:ffgggggg 6:ghhhhhhh
;Output	= 0:0aaaaaaa 1:0bbbbbbb 2:0ccccccc 3:0ddddddd 4:0eeeeeee 5:0fffffff 6:0ggggggg 7:0hhhhhhh
;30 bytes, 84 cycles (5.25 uS @16 MHZ)
unpack_recursive:
	ldi	ZH,high(iter1)	;Initialize iteration entry address pointer
	ldi	ZL,low(iter1)
	ldi	r24,low(it_lim)	;Set recursion limit checkpoint

			; Iter.1   Iter.2   Iter.3   Iter.4   Iter.5   Iter.6   Iter.7   Iter.8
iter1:	lsr	r16	;0aaaaaaa  --//--   --//--   --//--   --//--   --//--   --//--   --//--
iter2:	ror	r17	;bbbbbbbc 0bbbbbbb  --//--   --//--   --//--   --//--   --//--   --//--
iter3:	ror	r18	;ccccccdd cccccccd 0ccccccc  --//--   --//--   --//--   --//--   --//--
iter4:	ror	r19	;dddddeee ddddddee ddddddde 0ddddddd  --//--   --//--   --//--   --//--
iter5:	ror	r20	;eeeeffff eeeeefff eeeeeeff eeeeeeef 0eeeeeee  --//--   --//--   --//--
iter6:	ror	r21	;fffggggg ffffgggg fffffggg ffffffgg fffffffg 0fffffff  --//--   --//--
iter7:	ror	r22	;gghhhhhh ggghhhhh gggghhhh ggggghhh gggggghh gggggggh 0ggggggg  --//--
iter8:	ror	r23	;h0000000 hh000000 hhh00000 hhhh0000 hhhhh000 hhhhhh00 hhhhhhh0 0hhhhhhh

it_lim:	adiw	ZH:ZL,1	;Advance iteration entry pointer
	cpse	ZL,r24	;Check for recursion limit, exit if reached
	ijmp		;Do next iteration (iter+1) recursively

	ret

;Input	= 0:aaaaaaab 1:bbbbbbcc 2:cccccddd 3:ddddeeee 4:eeefffff 5:ffgggggg 6:ghhhhhhh
;Output	= 0:0aaaaaaa 1:0bbbbbbb 2:0ccccccc 3:0ddddddd 4:0eeeeeee 5:0fffffff 6:0ggggggg 7:0hhhhhhh
;74 bytes, 40 cycles (2.5 uS @16 MHZ)
unpack_inline:
; Iter.1
	lsr	r16	;0aaaaaaa
	ror	r17     ;bbbbbbbc
	ror	r18     ;ccccccdd
	ror	r19     ;dddddeee
	ror	r20     ;eeeeffff
	ror	r21     ;fffggggg
	ror	r22     ;gghhhhhh
	ror	r23     ;h0000000

; Iter.2
	lsr	r17	;0bbbbbbb
	ror	r18     ;cccccccd
	ror	r19     ;ddddddee
	ror	r20     ;eeeeefff
	ror	r21     ;ffffgggg
	ror	r22     ;ggghhhhh
	ror	r23     ;hh000000

; Iter.3
	lsr	r18     ;0ccccccc
	ror	r19     ;ddddddde
	ror	r20     ;eeeeeeff
	ror	r21     ;fffffggg
	ror	r22     ;gggghhhh
	ror	r23     ;hhh00000

; Iter.4
	lsr	r19     ;0ddddddd
	ror	r20     ;eeeeeeef
	ror	r21     ;ffffffgg
	ror	r22     ;ggggghhh
	ror	r23     ;hhhh0000

; Iter.5
	lsr	r20     ;0eeeeeee
	ror	r21     ;fffffffg
	ror	r22     ;gggggghh
	ror	r23     ;hhhhh000

; Iter.6
	lsr	r21     ;0fffffff
	ror	r22     ;gggggggh
	ror	r23     ;hhhhhh00

; Iter.7
	lsr	r22     ;0ggggggg
	ror	r23     ;hhhhhhh0

; Iter.8
	lsr	r23     ;0hhhhhhh

	ret
Для желающих проверить в работе - инициализация и вызов функции. После выполнения в соответствующем месте RAM появится слово "Keyboard" в ASCII-виде:
	ldi	r16,$FF&('K' << 1)|('e' >> 6)
	ldi	r17,$FF&('e' << 2)|('y' >> 5)
	ldi	r18,$FF&('y' << 3)|('b' >> 4)
	ldi	r19,$FF&('b' << 4)|('o' >> 3)
	ldi	r20,$FF&('o' << 5)|('a' >> 2)
	ldi	r21,$FF&('a' << 6)|('r' >> 1)
	ldi	r22,$FF&('r' << 7)|('d' >> 0)
	ldi	r23,0

	rcall	unpack_recursive
;	rcall	unpack_inline

foo:
	rjmp	foo