1

Bonjour, j'ai déjà rédiger ce message sur un autre site alors je C/C:

Je me suis lancé il y a peu dans l'assembleur pour pouvoir programmer sur Ti-83. J'ai donc essayé de faire mon premier programme à partir de fragments de tutoriaux pêchés à droite et à gauche.

C'est une version ASM du programme en Ti-Basic de quelques lignes que j'ai sur ma calculatrice. Ultra-classique, il calcule le discriminant, le sommet, et la/les racines d'un trinôme à partir de ses trois coefficients. C'est un premier programme pour me faire la main, mais ça ne marche pas vraiment.
Voici mon code:

#include "input.asm"
#include "begin.asm"

;------------------------> variables
varstart = 8265h
;--------------------------------------------------
;variable name value size description
;--------------------------------------------------
var_a =varstart+9 ;9 coefficient en x² du trinôme
var_b =var_a+9 ;9 coefficient en x du trinôme
var_c =var_b+9 ;9 dernier terme en x^0 du trinôme
var_delta =var_c+9 ;9 discriminant (b²-4ac)
var_sommet =var_delta+9 ;9 var_sommet du trinôme (-b/2a)

call _clrLCDFull

call _homeup
call _zeroop1

call _newline
ld hl,debut
call _puts
call _newline

;obention de a

ld de,PROMPT
ld hl,prompta
ld bc,3

call PGMIO_EXEC

;transfert de OP1 vers var_a

ld hl,op1
ld de,var_a
ld bc,9
ldir

;obention de b

ld de,PROMPT
ld hl,promptb
ld bc,3

call PGMIO_EXEC

;transfert de OP1 vers var_b

ld hl,op1
ld de,var_b
ld bc,9
ldir

;obention de c

ld de,PROMPT
ld hl,promptc
ld bc,3

call PGMIO_EXEC

;transfert de OP1 vers _c

ld hl,op1
ld de,var_c
ld bc,9
ldir

;
;calcul du sommet (-b/2a)
;

;transfert de var_b vers OP1
ld hl,var_b
ld de,op1
ld bc,9
ldir

;inversion du signe
call changesign

;transfert de var_a vers op1 pour la multiplication par deux
;auparavant, sauvegarde de -b (op1) vers op2
call _OP1TOOp2
ld hl,var_a
ld de,op1
ld bc,9
ldir

call _TIMES2

;on remet -b dans op1, et 2a dans op 2 pour la division finale

call _OP1TOOP3 ;on met 2a dans op 3
call _OP2TOOP1 ;on met -b dans op 1
call _OP3TOOP2 ;enfin, on remet 2a dans op2, et on peut faire la division

call _FPDIV

;enfin, on sauvegarde le résultat dans var_sommet:
ld hl,op1
ld de,var_sommet
ld bc,9
ldir

;
;transfet de B vers OP1 puis calcul de b²
;

ld hl,var_b
ld de,op1
ld bc,9
ldir

call _FPSQUARE

;on retransfert b²(op1) dans op3 et on calcule maintenant 4ac

call _OP1TOOP3

call _op1set4
ld hl,op2
ld de,var_a
ld bc,9
ldir

;on effectue 4*A

call _FPMULT

;on charge maintenant C dans op2

ld hl,var_c
ld de,op2
ld bc,9
ldir

call _FPMULT

;enfin, on fait b²(op3) - 4ac(op1)

call _OP1TOOP2 ;on met 4ac dans op2 car c'est le deuxième terme
call _OP3TOOP1 ;on remet b² dans op1
call _FPSUB

;on a notre var_delta, on fait maintenant en fonction des valeurs
;sauvegarde de var_delta
ld hl,op1
ld de,var_delta
ld bc,9
ldir

call _op2set0
call _cpop1op2

jp m,deltaneg
jp z,delta0
jp p,deltapos

deltaneg:
ld hl,nosolution
call _puts

delta0:
;affichage de la chaîne puis du var_sommet
ld hl,solution
call _puts

ld hl,var_sommet
ld de,op1
ld bc,9
ldir

call _formDisp

deltapos:
;calcul des deux racines (-b-sqrt(var_delta)/2a)
;d'abord, on calcule racine de var_delta : on stocke var_delta dans op1
ld hl,var_delta
ld de,op1
ld bc,9
ldir

call _SQROOT
call _OP1TOOP2 ;on met sqrt(var_delta) dans op2
call _OP1TOOP6 ;on garde également en mémoire la valeur pour les futurs calculs

;on place var_b dans op1
ld hl,var_b
ld de,op1
ld bc,9
ldir

;inversion du signe
call changesign

call _FPSUB ;on soustrait maintenant

;on stocke temporairement -b-sqrt(var_delta)[op1] dans op3 pour faire la multiplication 2*a
call _OP1TOOP3

;multiplication de a par deux
ld hl,var_a
ld de,op1
ld bc,9
ldir

call _TIMES2

call _OP1TOOP2
call _OP3TOOP1

call _FPDIV ;enfin après avoir retransférer les valeurs où il faut, on divise le tout

;on stocke la première racine dans op4
call _OP1TOOP4

;on réutilise la valeur de sqrt(var_delta) stockée dans op6
call _OP6TOOP2

;on place var_b dans op1
ld hl,var_b
ld de,op1
ld bc,9
ldir

;inversion du signe
call changesign

call _FPADD

;on stocke temporairement -b+sqrt(var_delta)[op1] dans op3 pour faire la multiplication 2*a
call _OP1TOOP3

;multiplication de a par deux
ld hl,var_a
ld de,op1
ld bc,9
ldir

call _TIMES2

call _OP1TOOP2
call _OP3TOOP1

call _FPDIV ;enfin après avoir retransférer les valeurs où il faut, on divise le tout

;on stocke la deuxième racine dans op5
call _OP1TOOP5

;on affiche ensuite les valeurs

ld hl,solutions
call _puts

call _OP4TOOP1
call _formDisp
call _OP5TOOP1
call _formDisp

changesign:
ld a,(op1)
cp 0
call nz,set_pos
call z,set_neg
ret

set_pos:
ld a,0
ld (op1),a
ret

set_neg:
ld a,$80
ld (op1),a
ret

debut:
.db "Calcul du discriminant",0
prompta:
.db "A:",0
promptb:
.db "B:",0
promptc:
.db "C:",0
nosolution:
.db "Pas de solutions",0
solution:
.db "Une solution:",0
solutions:
.db "Deux solutions:",0

.end
END

Quand je l'exécute sur VTI, j'ai juste une ligne verticale de pixel qui s'affiche à droite et ça plante. Avant, j'utilisais des variables comme promptb (déclarées dans le segmet data, comme .db etc...) à la place de var_a, var_b, etc... mais ça ne marchait pas mieux, les invite prompt ne s'affichaient pas, je rentrais quand même trois nombre et ça me mettait enfin "Error : Division by zero".

J'aimerai donc que vous me donniez des conseils déjà pour que mon programme fonctionne, et ensuite si possible sur les utilisations de tel et tel routine, sur la déclaration, sur le style, etc...
bref toute suggestion qui me serait utile.
Merci d'avance, @++

p.s: désolé, mais je n'ai pas trouvé la balise code xD pardonnez la lisibilité et la non-identation du code

2

Raté, tu n'es pas sur le bon forum (ici c'est Ti89/92/v200/NSpire); essaie de poser ta question ici. La balise pour poster du code est [pre].
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

3

Merci de l'info, j'ai copié mon message dans l'autre forum. Sujet à supprimer.
++