ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Четверг
9 мая
53386 Топик полностью
AVR (09.03.2006 18:06, просмотров: 1) ответил ReAl на Великолепный пример сравнивания С и ассемблера на РАЗНЫХ задачах.
Ладно, рукавами все же лучше меряться, чем пиписьками :) Вот код на фрейм ПРОИЗВОЛЬНОЙ длины - хоть до 64КБ, с указателем ессно. 118 bytes of code, 2504 cycles/156.5 uS @16MHZ per 256 output bytes. Си давай! :)) Куски fillram и filltab к делу не относятся - это для проверки в симуляторе. Для профилирования подставляем требуемое значение в buflen Целый час писал, минут 45 - только на комменты ушло :))
.nolist
#include	"m2561def.inc"
.list

.equ	packlen	= 7	;Packed bitstream length, bits
.equ	unplen	= 8	;Unpacked bitstream length, bits
.equ	buflen	= 2048	;Unpacked buffer size, up to (RAMSIZE-STACK) bytes
.equ	stack	= 64	;Stack size, bytes


.dseg
.org	SRAM_START+stack
buf:	.byte	buflen

.cseg
	ldi	r24,low(buf-1)	;Stack initialization
	ldi	r25,high(buf-1)	;
	out	spl,r24
	out	sph,r25

	rcall	fillram	;Fill BUFLEN RAM locations with repeating packed 7-byte test pattern


;
;
;
;Useful stuff starts here:
	ldi	ZL,low (buf+buflen)	;Load unpacked destination pointer
	ldi	ZH,high(buf+buflen)	;

	ldi	r24,low(buflen/8)	;Load repeat counter LSB
	ldi	r25,high(buflen/8)	;Load repeat counter MSB

;Reset cycle counter & stopwatch here
	rcall	unpack
;RAM @buf[(BUFLEN)] from now on is filled with unpacked pattern -
;ASCII "Keyboard" string repeated (BUFLEN/8) times

foo:
	rjmp	foo

;--------------------------------------------------------------------
unpack:
;Unpacks (BUFLEN*7/8) 7-bit packed bytes to BUFLEN unpacked bytes in RAM [buf]
;Code length = 118 bytes
; 86 cycles/5.4 uS @16MHZ per 8 output bytes
; 2504 cycles/156.5 uS @16MHZ per 256 output bytes
; 19976 cycles/1248.5 uS @16MHZ per 256 output bytes
; 79880 cycles/4992.5 uS @16MHZ per 8192 output bytes
	ldi	XL,low (buf+buflen*7/8)	;Load packed source pointer
	ldi	XH,high(buf+buflen*7/8)	;

unp_loop:
	ld	r6,-X	;Load last 7 packed bytes from RAM
	ld	r5,-X	;
	ld	r4,-X	;
	ld	r3,-X	;
	ld	r2,-X	;
	ld	r1,-X	;
	ld	r0,-X	;

	rcall	unpack_inline

	st	-Z,r7	;Save last 8 unpacked bytes to RAM
	st	-Z,r6	;
	st	-Z,r5	;
	st	-Z,r4	;
	st	-Z,r3	;
	st	-Z,r2	;
	st	-Z,r1	;
	st	-Z,r0	;

	sbiw	r24:r25,1	;Repeat BUFLEN times
	brne	unp_loop

	ret
;--------------------------------------------------------------------

;--------------------------------------------------------------------
unpack_inline:
;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
;76 bytes, 41 cycles (2.5625 uS @16 MHZ)

; Iter.1
	clr	r7	;To get CY = 0 from "ror r7"

	lsr	r0	;0aaaaaaa
	ror	r1	;bbbbbbbc
	ror	r2	;ccccccdd
	ror	r3	;dddddeee
	ror	r4	;eeeeffff
	ror	r5	;fffggggg
	ror	r6	;gghhhhhh
	ror	r7	;h0000000

; Iter.2
	lsr	r1	;0bbbbbbb
	ror	r2	;cccccccd
	ror	r3	;ddddddee
	ror	r4	;eeeeefff
	ror	r5	;ffffgggg
	ror	r6	;ggghhhhh
	ror	r7	;hh000000

; Iter.3
	lsr	r2	;0ccccccc
	ror	r3	;ddddddde
	ror	r4	;eeeeeeff
	ror	r5	;fffffggg
	ror	r6	;gggghhhh
	ror	r7	;hhh00000

; Iter.4
	lsr	r3	;0ddddddd
	ror	r4	;eeeeeeef
	ror	r5	;ffffffgg
	ror	r6	;ggggghhh
	ror	r7	;hhhh0000

; Iter.5
	lsr	r4	;0eeeeeee
	ror	r5	;fffffffg
	ror	r6	;gggggghh
	ror	r7	;hhhhh000

; Iter.6
	lsr	r5	;0fffffff
	ror	r6	;gggggggh
	ror	r7	;hhhhhh00

; Iter.7
	lsr	r6	;0ggggggg
	ror	r7	;hhhhhhh0

; Iter.8
	lsr	r7	;0hhhhhhh

	ret
;--------------------------------------------------------------------

;--------------------------------------------------------------------
fillram:
;Fills (BUFLEN*PACKLEN/UNPLEN) RAM locations @buf[(BUFLEN*PACKLEN/UNPLEN)]
;with repeating packed 7-byte test pattern @filltab from code memory

	ldi	ZL,low (filltab*2)	;Load buffer fill pattern address pointer
	ldi	ZH,high(filltab*2)	;(7-byte table in Flash)

	ldi	XH,high(buf)	;Load RAM buffer pointer
	ldi	XL,low (buf)	;

	ldi	r24,low(buflen/unplen)	;# of 7-byte patterns to copy LSB
	ldi	r25,high(buflen/unplen)	;# of 7-byte patterns to copy MSB

fillp:
	ldi	r16,packlen		;Set pattern byte counter

fill7:
	lpm	r0,Z+	;Read byte from Flash
	st	X+,r0	;Copy to RAM buffer
	dec	r16	;Repeat 7 times
	brne	fill7	;

	sbiw	ZH:ZL,packlen	;Rewind pattern ptr

	sbiw	r24:r25,1	;Repeat (BUFLEN/UNPLEN) times
	brne	fillp	;
	
	ret
;--------------------------------------------------------------------

filltab:
.db	$FF&('K' << 1)|('e' >> 6),\
	$FF&('e' << 2)|('y' >> 5),\
	$FF&('y' << 3)|('b' >> 4),\
	$FF&('b' << 4)|('o' >> 3),\
	$FF&('o' << 5)|('a' >> 2),\
	$FF&('a' << 6)|('r' >> 1),\
	$FF&('r' << 7)|('d' >> 0),0

.exit