Revenir au plan du site
Multiplication en assembleur Z80
Le Z80 est un processeur 8 bits, il n'est pas capable de réaliser nativement des divisions ou des multiplications. Voici une compilation de routines de multiplications (wikiti, Z80 heaven, grauw, cpcwiki)
8 x 8 multiplication non signée => HL
multiply_h_e
ld d,0
sla h
sbc a
and e
ld l,a
ld b,7
.loop
add hl,hl
jr nc,$+3 ; si le bit est présent, ajouter la puissance
add hl,de
djnz .loop
ret
|
Version déroulée plus rapide :
multiply_h_e
ld d,0
ld l,d
sla h ; injecter le premier bit
jr nc,$+3
ld l,e
repeat 6
add hl,hl
jr nc,$+3 ; si le bit est présent, ajouter la puissance
add hl,de
rend
add hl,hl
ret nc
add hl,de
ret
|
16 x 8 multiplication non signée => A:HL
multiply_de_a
ld bc,#700 ; B=7 init C=0
ld h,c
ld l,c
add a ; première itération optimisée
jr nc,.loop
ld h,d
ld l,e
.loop
add hl,hl
rla
jr nc,.skip
add hl,de
adc c ; comme C vaut zéro, ici on propage simplement la retenue dans A
.skip
djnz .loop
ret
|
Version déroulée plus rapide :
multiply_de_a
ld c,0
ld h,c
ld l,c
add a ; première itération optimisée
jr nc,.loop
ld h,d
ld l,e
repeat 6
add hl,hl
rla
jr nc,@skip ; le @ pour un label local dans une boucle REPEAT
add hl,de
adc c ; comme C vaut zéro, ici on propage simplement la retenue dans A
@skip
rend
; dernière itération
add hl,hl
rla
ret nc
add hl,de
adc c
ret
|
16 x 16 multiplication non signée => A:HL
multiply_de_bc
ld hl,0
; première itération
sla e
rl d
jr nc,.skipFirst
ld h,b
ld l,c
.skipFirst
ld a,15
.loop
add hl,hl
rl e
rl d
jr nc,.skipNext
add hl,bc
jr nc,.skipNext
inc de
.skipNext
dec a
jr nz,.loop
ret
|
Je vous laisse dérouler hein ;)
16 x 16 multiplication signée => DE:HL
multiply_de_bc ; résultat dans DE:HL
xor a
ld h,a : ld l,a ; HL = A = 0
bit 7,d
jr z,muldpos
sbc hl,bc
muldpos
or b
jp p,mulbpos
sbc hl,de
mulbpos
ld a,16
.loop
add hl,hl
rl e
rl d
jr nc,mul0bit
add hl,bc
jr nc,mul0bit
inc de
mul0bit
dec a
jr nz,.loop
ret
|