La multiplicationVous avez peut-être cherché dans la liste des instructions si une opération DIV ou MUL existait, afin de diviser ou multiplier. Comme la quasi totalité des processeurs 8 bits, le Z80ne sait pas faire de multiplications nativement. Il faut soit ajouter plusieurs fois de suite (le + simple, mais lent), soit utiliser une suite de décalages et additions (mieux). Ilreste la possibilité de précalculer des résultats de multiplication et d'utiliser des tables en mémoire, sachez que ça existe, mais nous verrons ça plus tard. La multiplication permet par exemple d'adresser une case dans un tableau à deux dimensions. Avec un tableau de 10 cases sur 10, si on souhaite le deuxième élément de la 3è ligne, il fautmultiplier le nombre de lignes par 10 et ajouter 2. Autrement dit, l'index de la case qu'on souhaite est index = largeur x rangée + colonne ; D=rangée ; E=colonne largeur=10 ; variable contenant la largeur de notre tableauLD HL,tableau ; on part de la première case, le début du tableau ; ajouter les lignes (ou rangées) LD A,D OR A JR Z,pasDeRangee ; si rangée vaut zéro, on n'additionne rien LD BC,largeur compteRangees ADD HL,BC DEC D ; on décompte le nombre de rangées JR NZ,compteRangees ; on recommence l'ajout tant que notre compteur ne vaut pas zéro pasDeRangee LD D,0 ADD HL,DE ; ajouter la colonne à l'index RET ; terminé, on renvoie l'adresse de la cellule dans HLCette routine est très simple et peu optimisée. Comme nos nombres sont binaires (base 2), cela signifie qu'un décalage des bits multiplie ou divise le nombre par deux. Pour de petites multiplications, il est plussimple de conserver cette boucle ou de faire quelques additions mais pour des nombres plus grands, la boucle devient trop lourde. On peut tester chaque bit de notre valeur et ajouter les puissances de 2 respectives,en fonction que ce bit soit présent ou non. ; E=rangée ; C=colonne largeur=10 ; variable contenant la largeur de notre tableauLD HL,0 ; on initialise notre accumulateur 16 bits à zéro LD D,H ; on va utiliser DE pour la valeur de la rangée, on met la partie haute à zéro LD B,8 ; on va multiplier par une valeur 8 bits multiply rrca ; on décale à droite pour mettre le bit le plus faible dans la carry jr nc,.noAdd ; si la carry est vide, pas d'addition add hl,de .noAdd sla de ; meta-instruction équivalente à [ sla e : rl d ], on multiplie DE par 2 djnz multiply ld b,0 ; on complète la partie haute de BC pour utiliser la valeur de la colonne toujours dans C add hl,bc ; on ajoute la colonne ld bc,tableau add hl,bc ; on ajoute l'offset du tableau RET ; terminé, on renvoie l'adresse de la cellule dans HLUn déroulé vaut mieux qu'on long discours : Si nous multiplions par exemple, par la valeur 10, il faut considérer la valeur binaire 10 (8+2) soit %1010. Admettons qu'on veuille multiplier 23 par 10. A=%1010, DE=23, HL=0
|