CODINGApprendre pas à pas la programmation en assembleur Z80 ★ Programmation avancée, routines utiles ★

Routines de division
Divisions 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 petite compilation de routines de division (wikiti, Z80 heaven, grauw, cpcwiki)


division 8 x 8 non signée => C

c_divise_par_d ; résultat dans le registre C
ld b,8
xor a
.loop
sla c
rla
cp d
jr c,.skip
inc c
sub d
djnz .loop
ret

division 16 x 8 non signée => C

hl_divise_par_c ; résultat dans HL, et le reste dans A
ld b,16
xor a
.loop
add hl,hl
rla
cp c
jr c,.skip
inc l
sub c
.skip
djnz .loop
ret

division 16 x 16 non signée => A:C

bc_divise_par_de ; résultat dans A:C, et le reste dans HL
ld hl,0
ld a,b
ld b,16
.loop
sll c
rla
adc hl,hl
sbc hl,de
jr nc,$+4
add hl,de
dec c
djnz .loop
ret

division 32 x 32 non signée BC':BC / DE':DE => IY:IX + remainder BC':BC
Suite au cours sur les divisions, voici la routine optimisée avec la méthode naïve. Si on compare avec des méthodes classiques, elle est beaucoup plus rapide (genre, beaucoup, presque 10 fois plus rapide) quand le résultat est petit et 50% plus lent quand le résultat est trèèèès grand.

Selon vos cas d'usage et les besoins en mantisse, utilisez l'une ou l'autre. J'ai comparé avec celle de [ Zeda ], seuleque j'ai finalement trouvée (Merci Prodatron!) permettant de diviser deux nombres 32 bits.

Par ailleurs, le code n'utilise pas de mémoire vive et repose uniquement sur les registres.

; Z80 division 32 bits unsigned
div32unsigned
; input :
; dividende in BC':BC
; divisor in DE':DE
; output :
; result in IY :IX
; remainder in BC':BC
;
; this function is suitable for ROM usage (no memory is used)
; this function can be enhanced to not use STACK (remove the RET and add a JR at the end)
; known limitation => divisor on 31 bits maximum
; speed depends on result size
; (expect from 100 nops for a small quotient to 2000 nops for a big quotient)

; find max iterations to do and prepare divisor
xor a
jr .firstIterationQbit

.findMaxQbit
sla de : exx : rl de : exx ; divisor x 2
.firstIterationQbit
inc a : ld hl,bc : or a : sbc hl,de : exx : ld hl,bc : sbc hl,de : exx : jp nc,.findMaxQbit ; compare dividende to divisor
.maxQ cp 1 : jr z,.noadjust : exx : srl de : exx : rr de : dec a : .noAdjust

; initialise quotient
ld ix,0
ld iy,0
; iterate using binary
jr .firstIteration

; compute quotient with almost ALL registers available
.computeQuotientBit
add iy,iy : add ix,ix : jr nc,.NextIteration : inc yl ; shift quotient
.firstIteration
or a ; reset Carry for next SBC
.NextIteration
ld hl,bc : sbc hl,de : exx : ld hl,bc : sbc hl,de : jp c,.bit0 ; cannot substract => 0
.bit1
; update remainder + shift divisor
ld bc,hl : srl de : exx : rr de : ld bc,hl
inc xl ; inject bit to quotient
dec a : jr nz,.computeQuotientBit
ret

.bit0
; do not touch remainder, shift and loop
srl de : exx : rr de ; shift divisor
dec a : jr nz,.computeQuotientBit
ret

Vous pouvez jeter un oeil dans les liens pour trouver encore plus de routines différentes, en particulier sur les sites de calculatrices Texas Instrument.

★ ANNÉE: 2025
★ AUTEUR: Roudoudou

Je participe au site:

» Vous avez remarqué une erreur dans ce texte ?
» Aidez-nous à améliorer cette page : en nous contactant via le forum ou par email.

CPCrulez[Content Management System] v8.732-desktop/c
Page créée en 140 millisecondes et consultée 8 fois

L'Amstrad CPC est une machine 8 bits à base d'un Z80 à 4MHz. Le premier de la gamme fut le CPC 464 en 1984, équipé d'un lecteur de cassettes intégré il se plaçait en concurrent  du Commodore C64 beaucoup plus compliqué à utiliser et plus cher. Ce fut un réel succès et sorti cette même années le CPC 664 équipé d'un lecteur de disquettes trois pouces intégré. Sa vie fut de courte durée puisqu'en 1985 il fut remplacé par le CPC 6128 qui était plus compact, plus soigné et surtout qui avait 128Ko de RAM au lieu de 64Ko.