Additionner et soustraire des nombres sur 64 bits
7 sujets de 1 à 7 (sur un total de 7)
-
Voici un petit bout de code
_add64
adda #8,A0
adda #8,A1
addx.l -(A1),-(A0)
addx.l -(A1),-(A0)
rts
bien sûr compilé en assembleur et exploité en C.
Dans l’emplacement pointé par A0 on a bien alors la somme des deux valeurs 64bits pointés par A0 et A1.
Si on fait la même chose avec subx à la place de addx, on obtient pas la soustraction escomptée… sur WinUAE, et comme je n’ai plus de vrai 68000 pour tester, est-ce normal ce comportement de subx?
Bonjour,
Il me semble que c’est normal car subx.l src, dst correspond à dst = src – dst.
Dans votre cas, le résultat devrait être (A0) = (A1) – ( (A1) – (A0) ) et non (A0) = (A0) – (A1) – (A1).
hum…
@all (:-o ze solution!)
addx et subx utilisent la partie arithmétique du 68000 pour faire des additions et soustractions à retenue (le X du registre CCR, registre des conditions) bien sûr cette retenue se propageant de droite à gauche, il faut parcourir la mémoire à reculons, d’où l’adressage -(Ax),-(Ax) (et pas l’explication vaseuse de sieur doudou)
J’avais fait 2 bêtises:
bêtise 1) pour effacer X, il faut juste faire une addition simple sur un registre d’adresse, et pas utiliser adda, qui ne touche pas au CCR.
bêtise 2) c’est de l’arithmétique non signée.
si on fait 5 – 10 on n’obtient pas -5, mais une valeur quelconque avec un overflow (V dans le CCR)
_add64
add.l #8,A0
add.l #8,A1
addx.l -(A0),-(A1)
addx.l -(A0),-(A1)
rts
_sub64
add.l #8,A0
add.l #8,A1
subx.l -(A0),-(A1)
subx.l -(A0),-(A1)
rts
Donc le 68000 et sa descendance savent d’origine bricoler des entiers non signés sur 8, 16, 32, 64, 128, 256, 512 bits et j’en passe. Il m’étonnera tous les jours ce processeur.
En fait ta gestion du X du registre CCR n’est toujours pas correcte.
Si tu désassemble add.l #8,A0 tu verras qu’en fait c’est codé en adda.l #8,A0, parce qu’en réalité il n’est pas possible d’utiliser add sur un registre d’adresse.
Le bon code est celui-ci, car tu n’as pas besoin de prendre en compte X pour l’addition de poids faible :
_add64
adda.l #8,A0
adda.l #8,A1
add.l -(A0),-(A1)
addx.l -(A0),-(A1)
rts
Pour la question du signe ça marche très bien si tu veux de l’arithmétique signée puisque le bit N du registre CCR est positionné correctement. Le résultat de 5 – 10 est le complément à 2 de 5 en 64 bits, soit $ FFFF FFFF FFFF FFFB.
@BrickCaster tu es un chef ! ! !
Car c’est bien la première fois que je vois add.l -(A0),-(A1)
en principe c’est add.l Dx,ketchose ou add.l ketchose,Dx alors pour mettre court à toute rumeur, je mets le dernier code qui marche bien, même avec des entiers négatifs:
_add64 move.l D0,-(SP)
moveq #8,D0
add.l D0,A0
add.l D0,A1
move.l -(A0),D0
add.l D0,-(A1)
addx.l -(A0),-(A1)
move.l (SP)+,D0
rts
_sub64 move.l D0,-(SP)
moveq #8,D0
add.l D0,A0
add.l D0,A1
move.l -(A0),D0
sub.l D0,-(A1)
subx.l -(A0),-(A1)
move.l (SP)+,D0
rts
ModYop Gilloo,
Googlant le sujet, je n’ai trouvé que cela concernant la division :
++
7 sujets de 1 à 7 (sur un total de 7)
- Vous devez être connecté pour répondre à ce sujet.
› Forums › AmigaOS, MorphOS et AROS › Développement › Additionner et soustraire des nombres sur 64 bits