Fermer2
FarewellLe 06/03/2010 à 23:04
Bon, je cherche des optimisations vitesse de cette routine (primordial), la taille je m'en fous un peu)
;==========================================================
;	CompareStrings
;
;	Check if the string RefString terminated by a char of SeparatorTable is contained
;	in the string table StringTable
;	Return #item in the table, or -1 if the string isn't in the table. First item is #0
;	Put in NextChar a ptr to the next char after RefString if NextChar != NULL
;
;	input	a0	StringTable
;		a1	SeparatorTable
;		a2	RefString
;		a3	**char (NextChar)
;	output	d0.w	#item, else <0
;		(a3)	updated if a3 != 0
;	destroy	d0-d2/a0
;==========================================================
butillib@0006:
	movem.l	a1/a4,-(sp)		; Save RefString
	moveq.l	#-1,d0			; #item
\ItemLoop:
	addq.w	#1,d0			; Update #item
	movea	a2,a1			; RefString
\Loop:	move.b	(a0)+,d1		; End of string in StringTable ?
	beq.s	\CheckSeparator		; Yes, so check the separator at -1(a0)
	cmp.b	(a1)+,d1		; Compare strings
	beq.s	\Loop			; Until mismatch
\NextString:
	tst.b	(a0)+			; Else skip current string
	bne.s	\NextString
\CheckEOT:
	tst.b	(a0)			; End of StringTable ?
	bne.s	\ItemLoop		; No, continue
		moveq.l	#-1,d0		; Else return error code
		bra.s	\NoSaveNextChar


\CheckSeparator:
	move.b	(a1),d1			; Current char of RefString
	beq.s	\Quit			; #0 ? So quit, EOF is always a valid separator
	movea.l	(sp),a4			; SeparatorTable
\LoopSeparator:
	move.b	(a4)+,d2		; End of SeparatorTable ?
	beq.s	\CheckEOT		; Yes, try with the next string
	cmp.b	d1,d2			; Equal ?
	bne.s	\LoopSeparator		; No, test with next char
\Quit:
	move.l	a3,d1			; Must save *NextChar ?
	beq.s	\NoSaveNextChar		; No
		move.l	a1,(a3)		; Else save it
\NoSaveNextChar:
	movem.l	(sp)+,a1/a4
	rts

Les règles :
- d0-d2/a0-a1 peuvent être détruits, mais le résultat doit être dans d0.
- pas de smc ou de relogement
- les romcalls sont utilisables (mais bon... on parle optimisation ici grin)

Les données :
a0 : StringTable -> une suite de chaines C suivies d'un 0 supplémentaires : dc.b "abc",0,"def",0,0
a1 : SeparatorTable -> une chaine C contenant les séparateurs acceptés : dc.b ":?!. \n",0. '\0' est toujours un séparateur valide.
a2 : RefString -> La chaine dont on cherche une correspondance dans StringTable
a3 : **char (NextChar) -> Adresse où l'on stocke l'adresse du séparateur marquant la fin de la chaine. On y enregistre rien si a3=NULL. On peut y stocker quelque chose même si on ne trouve pas de correspondance (ça sera donc invalide, mais le succès de la fonction est vérifié avec d0, ségatif si on a pas trouvé de chaine qui matche dans la table).

Bon d'après Zerosquare, c'est assez bien foutu, mais on pense pouvoir tirer encore quelques grammes ici ou là ^^