Revenir au plan du site


Astuces en vrac d'optimisation de code assembleur Z80


Plutôt que
ld a,0 ; + lent mais ne change pas les flags!

Écrivez ceci
xor a ; 1 octet de moins, 1 nop de moins (change les flags!)


Plutôt que
sla a ; A = A x 2

sla h
rl l ; HL = HL x 2

Écrivez ceci
add a ; A = A x 2

add hl,hl ; HL = HL x 2


Plutôt que
ld b,10
ld c,50

Écrivez ceci
ld bc,(10<<8)|50 ; 1 octet de moins, 1 nop de moins


Plutôt que
ld a,#DD
ld (hl),a

Écrivez directement ceci
ld (hl),#DD ; 1 octet de moins, 1 nop de moins


Plutôt que
ld a,(variable)
inc a
ld (variable),a ; total de 7 octets et 9 nops

Écrivez ceci (vous pouvez même supprimer la dernière ligne si vous n'avez pas besoin de HL ensuite, c'est encore plus rapide)
ld hl,variable
inc (hl)
ld a,(hl) ; total de 5 octets et 8 nops


Plutôt que
ld a,(hl)
ld (de),a
inc hl
inc de ; total de 4 octets et 8 nops

Écrivez ceci
ldi
inc bc ; total de 3 octets et 7 nops


Plutôt que
cp 0

Écrivez ceci
or a


Plutôt que
neg
add valeur

Écrivez ceci
cpl
add valeur+1


Plutôt que
ld a,b
neg

Écrivez ceci
xor a
sub b


Plutôt que
cp valeur
jr c,label
jr z,label ; note: c'est bien deux fois le même label utilisé

Écrivez ceci
cp valeur+1
jr c,label


Plutôt que
call routine
ret

Écrivez ceci
jp routine


Plutôt que
or a : jp z,A_vaut_zero
cp 1 : jp z,A_vaut_un
cp 2 : jp z,A_vaut_deux
...

Écrivez ceci (pour beaucoup de valeurs, utilisez une lookup table)
or a  : jp z,A_vaut_zero
dec a : jp z,A_vaut_un
dec a : jp z,A_vaut_deux
...

Avec une lookup
add a
ld (recupSaut+1),a
recupSaut ld hl,(table_de_sauts)
jp (hl)

align 256
table_de_sauts ; table alignée sur 256 octets
defw saut1,saut2,saut3,saut4,saut5,saut6
...

Par extension si on ne part pas de zéro...
Plutôt que
cp 40 : jp z,A_vaut_40
cp 41 : jp z,A_vaut_41
cp 42 : jp z,A_vaut_42
...

Écrivez ceci (pour beaucoup de valeurs, utilisez une lookup table)
sub 40 : jp z,A_vaut_40
dec a  : jp z,A_vaut_41
dec a  : jp z,A_vaut_42
...

Avec une lookup
sub 40 ; ou alors remplir le début de la table avec 40 sauts factices
add a
ld (recupSaut+1),a
recupSaut ld hl,(table_de_sauts)
jp (hl)

align 256
table_de_sauts ; table alignée sur 256 octets
defw saut1,saut2,saut3,saut4,saut5,saut6
...


Plutôt que
dec bc
ld a,b
or c
ret z ; ou autre saut conditionnel sur zéro

Écrivez ceci
cpi ; incrémentation de HL au passage
ret po


Plutôt que
cp 1

Écrivez ceci
dec a


Plutôt que
bit 0,a
jr z,label

Écrivez ceci
rra
jr nc,label


Plutôt que
bit 7,a
jr z,label

Écrivez ceci
rla
jr nc,label


Plutôt que
ld l,(hl) ; multiplication par 64 d'une valeur
ld h,0    ; pointée par HL
add hl,hl
add hl,hl
add hl,hl
add hl,hl
add hl,hl
add hl,hl

Écrivez ceci
ld h,(hl) ; récupérer dans le poids fort
ld l,0    ; pour multiplier par 256
srl hl
srl hl ; voir chapitre des supers instructions ;)


Pour les grosses copies mémoire, plutôt que
ldir

Écrivez cette fonction
FastLDIR ; thanks grauw
xor a
sub c
and 15
add a
ld (.automod+1),a
.automod jr nz,$ ; code automodifié
.loop
repeat 16 : ldi : rend
jp pe,.loop


Plutôt qu'un LDIR
ldir

Cette version précalcule le saut à la compilation pour être encore plus rapide mais ne traite pas les longueurs dynamiques
repeat 64,x
ldi64_sub{64-x} ldi
rend
jp pe,ldi64
ret

macro ultraFastLDIR longueur
lngmod=longueur%64
ld bc,{longueur}
call ldi64_sub{lngmod}
mend


Évitez de soustraire quand c'est possible
ld de,2000
xor a ; obligé de mettre la carry à zéro!
sbc hl,de

Écrivez ceci
ld de,-2000
add hl,de