Programmer en hexadécimal ... c'est possible !!!
+10
vazerd
Le Grec
nikitouzz
linkakro
Metallica
Alexis
sandro
noelthebest
persalteas
matrefeytontias
14 participants
Page 1 sur 6
Page 1 sur 6 • 1, 2, 3, 4, 5, 6
Programmer en hexadécimal ... c'est possible !!!
¡ Hola la gente !
J'ai demandé il y a un peu de temps s'il existait un tutoriel d'hexadécimal, pour pouvoir programmer on-calc en autre chose qu'en Ti-basic. On m'a dit que ça ne devait pas exister, vu la complexité du truc. Alors comme je suis maso ( ) j'ai décidé d'apprendre l'hexa tout seul (et là j'ai compris pourquoi y'a pas de tutos ).
Toujours est-il que si vous voulez programmer on-calc, que vous ne comptez pas vous relire un jour et que vous aimez les challenges, vous pouvez programmer en hexadécimal .
Donc ben je me suis dit "tiens ben je m'en sors pas trop mal, j'ai qu'à en faire profiter les gens ça leur évitera de souffrir inutilement. Alors ben voilà, je vous dit ce que je sais et j'édite au fur et à mesure
Ah oui aussi : ce dont je vais parler ici c'est de l'hexadécimal pour Ti-83 , 83 SE, 84 et 84 SE. N'essayez pas de suivre avec une autre calto, tout ce que vous allez faire c'est la ruiner un maximum.
J'ai modifié l'ensemble du tuto pour qu'il soit compatible 82 stats.
L'hexa des deux calculatrices est le même de toute façon, à part quelques petits trucs, c'est pour ça que ça mérite des précisions
De plus, je pars du fait que vous "avez déjà entendu parler de l'ASM". Donc faut savoir ce qu'est une romcalls, un registre, une variable et une adresse en gros.
ATTENTION : CE QUE JE VAIS VOUS APPRENDRE EST EXCEPTIONNELLEMENT DANGEREUX. TOUS LES EXEMPLES QUE JE PRÉSENTERAI AURONT ÉTÉ PRÉALABLEMENT TESTÉS SUR ÉMULATEUR. TOUT DOMMAGE À VOTRE CALCULATRICE DÛE À UNE FAUTE DE COPIE NE SAURA M'ÊTRE IMPUTÉE.
Introduction : registres, variables, adresses, romcalls et autres joyeusetés
Pour ceux qui ne connaissent pas encore l'ASM, vous ne comprendrez sûrement pas le tuto dans son intégralité. C'est pourquoi je vais vous expliquer rapidement les rudiments de ce langage (et donc de l'hexadécimal).
Les registres
Vous vous rappelez de vos variables prédéfinies A, B, C ... Z, thêta en Ti-Basic ? Oui ? Parfait, oubliez-les. Les variables en ASM n'ont absolument rien à voir avec celles que vous connaissiez jusqu'à présent.
En ASM, d'une part les "variables" dont je parle actuellement ne sont pas de vraies variables, les "variables" en ASM c'est autre chose.
En ASM et en hexadécimal on va parler de registres. Ce sont des emplacements mémoires (variables selon le contexte) qui vont servir à contenir uniquement des nombres. En ASM comme en hexa, tout se fait avec des nombres.
Il existe des registres 8 bits (c'est-à-dire qui contient un chiffre entre 0 et 255 en décimal, $FF en hexadécimal et 111111 en binaire) appelés A, B, C, D, E, F (qui n'existe pas en hexadécimal et qu'on utilise pas directement en ASM), H et L. On peut les utiliser comme simples zones où stocker des données (à part F).
A est un peu spécial : c'est l'accumulateur. C'est sur lui qu'on va effectuer des opérations. Par exemple, il est impossible d'ajouter une valeur à B, on doit obligatoirement passer par A.
Il existe également des registres 16 bits (qui contiennent un nombre entre 0 et 65535 en décimal, $FFFF en hexa et 11111111111111 en binaire). Ce sont en fait des combinaisons de registres 8 bits : AF (modifié au même titre que F), BC, DE et HL.
Les 8 bits et 16 bits correspondent : si vous modifiez H, alors HL lui aussi va être modifié, dans sa partie "du haut" : en effet, si on met séparément :
Les adresses
Ce sont les "zones de mémoire" dont je parlais. Elles sont définies en général par un chiffre hexa (toujours de 16 bits, donc entre $0000 et $FFFF) et sont entre parenthèses (en ASM ; en hexa c'est plus compliqué). Elles vont, quand on les appelle, orienter le programme vers la valeur situé à l'adresse appelé. Par exemple, si B se situe à $0075 et qu'on appelle H = ($0075), alors H vaudra B.
Elles sont un peu compliquées à utiliser en hexa, donc on les verra plus tard. Toujours est-il qu'on peut leur assigner n'importe quelle valeur, mais toujours à travers A ou un registre 16 bits.
Les romcalls
Ce sont les équivalents des fonctions en Ti-Basic. Par exemple, ClrHome en Ti-Basic s'appelle ClrLCDFull en ASM et $4540 en hexa. Pour appeler une romcall en ASM, on entre :
Les romcalls "ne prennent jamais d'arguments". On serait tentés de dire ça sachant qu'en ASM la fonction d'appel d'une romcall ne laisse pas de place pour des arguments.
En réalité, une romcall utilise comme arguments registres ou adresses, auxquels on aura assigné la bonne valeur au préalable. Bien sûr, une romcall n'utilise pas systématiquement tous les registres.
Les variables
En ASM, les variables sont simplement des noms assignés à des adresses pour faciliter leur utilisation. En hexadécimal, les variables n'existent pas vu qu'on ne manipule que des chiffres. Je ne m'étendrai donc pas dessus.
Les opérateurs
La notion d'opérateur est compliquée en ASM. Ce n'est pas une romcall, pas un registre, pas une adresse. Pour vous donner un exemple, l'opérateur ld prend en arguments deux registres, et stocke la valeur du deuxième dans le premier :
Un autre exemple ; l'opérateur ADD prend deux arguments : le registre A (je me demande encore pourquoi il est obligatoire de le préciser) et une valeur à lui ajouter (registre, adresse, chiffre ...).
Comme je disais, les opérateurs sont nombreux et compliqués, on en parlera donc plus tard.
Bon, maintenant nous voilà prêts à attaquer l'hexadécimal !
Créer un programme hexadécimal
Sur Ti-83
Pour créer un programme hexa sur une des calculatrices ci-dessus (les autres fichez le camp ), c'est au moins aussi simple que créer un programme Ti-basic : on va dans [prgm] NOUVEAU et on tape le nom de son programme.
Par contre, si on en reste là la calto va réellement croire que c'est un programme Ti-basic. Donc on va signaler notre identité en ajoutant le token (ou mot-clé) AsmPrgm (uniquement via le catalogue), comme ça elle est bien mise au courant.
Sinon à part ça, je vous dit tout de suite comment exécuter un programme hexa, c'est pas beaucoup plus compliqué. Pour info, ça se lance exactement de la même manière qu'un programme ASM :
Enfin non, en réalité y'a deux façons :
Pour compiler un programme hexa, on a une commande tout prête appelée AsmComp() (toujours via le catalogue) qui prend en premier argument le programme à compiler et en deuxième argument le nom du fichier de sortie (qui ne doit évidemment pas déjà exister sous peine d'une ERROR:DUPLICATE). Le résultat sera un programme deux fois plus léger et rapide à lancer avec la première méthode. Un exemple pour illustrer le tout et on s'y met :
Pour 82 stats
C'est pareil que pour 83 , mis à part le format du fichier. Alors que sur 83 on a :
À peine plus long, mais attention à pas vous tromper, ça ferait planter la calto.
Sur 82 stats, il n'y a pas de commande Asm( ), mais rassurez-vous on peut quand même lancer des programmes ASM :
Par contre, impossible de compiler un code hexa sur 82 stats.
Le header en hexadécimal
Si vous connaissez l'ASM (je vais faire comme si), vous vous rappelerez sûrement du header, à écrire au début de chaque programme ASM. Ce header ressemblait plus ou moins à ça :
Ici rien de tout cela : comme en hexadécimal on n'utilise pas de lettres (ben oui A B C D E F c'est des chiffres je vous rappelle ) on n'a pas à s'embarrasser de conventions, de casse ou de quoi que ce soit.
Ce qui fait que notre beau header pimpant se résume en :
AsmPrgm est un token qui indique à la calto que le programme est en hexa (un peu comme le End:0000:End des 82 stats). Il va être remplacé à la compilation par $BB6D.
Ce BB6D, d'où sort-il ? Et bien c'est simple : c'est un token. Si si promis.
En fait le token AsmPrgm a pour code hexa $BB6C. C'est le token commençant un programme hexa (ou ASM précompilé). Et le token ayant pour code $BB6D est le token AsmCmp. Vous ne le verrez jamais puisque par défaut la calculatrice dit que chaque programme commençant par ce token est de l'ASM compilé et doit être inaccessible à l'édition. C'est pour ça qu'on ne peut pas éditer certains programmes, parce qu'ils commencent par ce token.
Structurer son code hexadécimal
L'avantage avec le code hexadécimal, c'est que comme justement il est en hexadécimal, il ne comprend pas les sauts de ligne tant qu'ils ne coupent pas un octet en deux (on va voir ça). Par contre, il comprend les espaces, et il saura bien vous le dire via une ERROR:SYNTAX.
ATTENTION : si votre code hexa comporte une erreur détectée par la calto, appuyer sur Goto ne sert à rien, ça vous renverra à la fin de la commande Asm().
Donc je viens de dire que la calto n'est pas gênée par les sauts de ligne tant qu'ils ne coupent pas un octet en deux. Et c'est vrai :P
Les "commandes" en hexadécimal (on ne peut pas vraiment les appeler comme ça mais bon) s'écriront toujours tout le temps de la même manière : des groupes de deux chiffres hexadécimaux. Sachant qu'un chiffre hexa traduit 4 bits et forme ce qu'on appelle un quartet, deux chiffres hexa traduisent 8 bits en formant un octet. C'est la position des bits qui va donner le token à interpréter.
Donc disais-je, si dans un accès de frustration et de rage contre votre calculatrice vous insérez un saut de ligne entre deux quartets qui correspondent, elle va pas être d'accord et vous le fera savoir via une ERROR:SYNTAX !
Exemple :
En fait c'est simple, si vous voyez une ligne comprenant un nombre impair de chiffres, c'est pas bon.
Aussi, en ASM les programmes finissent tous par RET (l'instruction qui finit le programme). Ben là c'est plus RET c'est C9. Donc si vous ne mettez pas C9 à la fin de chaque programme, ça risque de bousiller votre calto en moins de temps qu'il n'en faut pour le dire. On a donc un code minimal qui ne fait rien :
Dernière chose, au niveau de la lisibilité (si lisibilité il y a ), essayez au maximum de donner une structure cohérente à votre code. C'est à dire, mettez une instruction par ligne, pas deux, pas trois et encore moins une moitié d'instruction. Parce que oui, on peut mettre des "moitiés" d'instruction. Donc en gros pour mettre $54D1 dans DE et $41E6 dans HL faites ça :
Et pas ça :
Bon, ben cette fois on est paré, on peut y aller ! À l'assauuuuut !!!
Les registres et l'assignation en hexadécimal
Aïe ...
À partir d'ici la vraie galère commence.
Après des heures de dur labeur, j'ai enfin trouvé toutes les adresses des registres !!!!! [Vous devez être inscrit et connecté pour voir cette image]
Commençons avec les registres. Ben c'est les mêmes qu'en ASM c'est juste qu'ils s'appellent pas pareil
Par exemple, en hexadécimal, hl s'appelle $21. Et encore, pas tout le temps.
Ah oui non parce qu'en plus de faire la même chose MAIS de s'appeler pas pareil, faut EN PLUS qu'ils jouent les schyzophrènes à changer de nom selon le contexte par exemple, si vous voulez mettre une valeur dans DE il va s'appeler $11, mais si vous voulez mettre DE dans un autre registre il va s'appeler autrement !!! Si c'est pas juste pour faire ch*er les gens ça !
L'assignation classique : valeur hexadécimale vers registre
C'est le cas le plus courant, qui correspond à assigner une valeur hexadécimale (on fait de l'hexa je rappelle [Vous devez être inscrit et connecté pour voir cette image] ) à un registre. En ASM, on fait comme ça :
Oui, en fait AF et F n'existent pas, puisque les flags sont gérés directement en hexadécimal (on n'utilise pas F).
On remarque que les adresses de tous les registres 8 bits (sauf A) peuvent être devinés dès qu'on connaît celle de B ($06). En effet, chacun de ces registres étant de 8 bits, par exemple pour trouver C on a juste à faire B $08, ce qui donne $0E, et ainsi de suite. C'est pareil pour les registres 16 bits à partir de BC ($01) auquel par exemple pour trouver DE on ajoute 16, soit $10. Donc, DE est bien situé à $11.
Alors c'est sûr que niveau optimisation c'est du jamais vu mais je vous dis pas combien j'ai galéré pour comprendre la signification de ces deux octets qui ressemblent à rien !
Donc, pour assigner $42 (donc 66) à E, on fera :
Dans le même esprit, ici on assigne $3D94 à HL :
L'assignation registre vers registre
Accrochez-vous, là ça devient vraiment compliqué.
Les registres 8 bits
Pour assigner un registre à un autre registre, la théorie est très simple et l'application très compliquée : en effet, cette commande en ASM :
Donc disais-je, pour assigner un registre à un autre, on doit spécifier le nom du registre cible avec un premier quartet, et le nom du registre source avec le deuxième quartet.
MAIS si c'était juste ça ça serait trop facile ! Ah ben non mais c'est pas marrant comme ça !
Donc en fait, le nom du registre source varie en fonction du registre cible. En Français compréhensible [Vous devez être inscrit et connecté pour voir cette image] , si on veut faire
Mais le PIRE, c'est qu'il y a des registres cibles qui s'appellent pareil ! Et là croyez-moi c'est vraiment le ouaï quand on se met à utiliser beaucoup de registres.
Pour commencer, les registres sources :
Mais alors vous allez me dire, comment lors d'une assignation différencier B et C ? D et E ? H et L ? Et ben c'est simple non pas du tout en fait [Vous devez être inscrit et connecté pour voir cette image] : en fonction du registre source. Heureusement, vous n'avez que deux registres source à connaître :
À partir de B, vous pouvez calculer C, D, E, H et L simplement en ajoutant $01.
ATTENTION : faites très attention au registre cible ! Je ne sais pas ce que ça va donner si pour assigner C à D vous faites
Voici un tableau pour résumer tout ça :
Vous êtes toujours vivants ? [Vous devez être inscrit et connecté pour voir cette image] Alors faisons un petit exercice pour que ça soit définitivement clair dans votre tête.
En hexadécimal, faites un programme complet (qu'on pourrait lancer sur la calto) qui assigne :
ATTENTION : on écrit d'abord la cible et ensuite la source, comme pour la commande ld !
En fait, ce n'est pas par pur sadisme ou par haine contre les programmeurs qu'on utilise ce système. C'est parce qu'on a vu ici les registres 8 bits, et "bizarrement", vous voyez que les registres cibles vont 2 par 2 ... et que les sources s'étendent toujours sur 8 bits ... ah tiens
Et si on y regarde un peu plus près, sur A par exemple : selon la cible, il vaut 7 ou F ...
Mais attends $F - $7 = $8 !!!!
Et oui, il y a une véritable raison à ce système. Chaque registre prend 8 bits, mais comme il n'y a aucun espace de mémoire libre, on est obligé de mettre deux registres 8 bits dans un seul emplacement 16 bits.
CQFD.
Les registres 16 bits
Avec les registres 16 bits, c'est très simple : on fait pas . Ben oui carrément, on ne peut pas stocker des registres (8 ou 16 bits) dans un registre 16 bits. Que des adresses, on verra ça beaucoup plus tard.
Les romcalls
Là c'est bon, j'ai trouvé tout ce qu'il fallait, ce sera un des rares chapitres complets Pour appeler une romcall en ASM, vous utilisiez :
Hé ben bonne nouvelle : en hexa c'est pareil !
Sur 82 stats EF ne sert pas à ça ! Utilisez toujours CD (call) à la place !
Aaaaah ! Enfin un truc simple !
Donc récapitulons, sachant qu'en ASM pour effacer l'écran on fait :
En hexa on fait ..? Allez devinez !
Pour les romcalls qui utilisent des arguments, c'est comme en ASM : on a juste à assigner la bonne valeur au bon registre et appeler la romcall qui va l'utiliser paisiblement. Vous plaignez pas, pour une fois que y'a un truc facile
Par contre il va y avoir un autre gros problème, c'est au niveau des romcalls, pour savoir où elles se situent, parce que je pense pas que ça vous éclate de retenir des adresses comme ça
C'est pourquoi je vous conseille de télécharger le fichier include ultimate.inc qui contient les adresses de tellement de trucs et de machins que vous allez faire un overflow si vous essayez de tous les compter
Pour Ti-82 stats, utilisez ti83asm.inc, car les adresses des romcalls varient de la 82 stats à la 83 .
Et donc grâce à ces fichiers, vous aurez toutes les adresses de n'importe quoi sous la main.
Après le C9 ...
En ASM, y'a plein de trucs après le RET. Par exemple les .db ou les autres labels.
Ben en hexa c'est plus ou moins la même chose, on a l'instruction C9 puis encore tout plein de trucs.
Alors je ne vous parlerai ici que du cas de la chaîne de caractère parce que je connais que celui-là, donc m'en voulez pas trop hein
En ASM, pour rajouter une chaîne à un label vous mettiez un .db non ? Ben pas en hexa. En hexa pour les chaînes comme ça c'est l'anarchie totale, on écrit C9, on saute une ligne pour faire bô et on balance la chaîne comme ça sans rien. Chaîne bien sûr codée en hexa, à partir de A = 65 = $41 et on ajoute $1 pour monter d'une lettre dans l'alphabet.
Je ne sais pas encore comment utiliser ces chaînes, mais promis je saurai bientôt !
Mini-TP surprise
Parce que je pense vous avoir appris assez de trucs pour pouvoir les mettres en oeuvre, je vous demande maintenant de créer votre premier programme entièrement hexadécimal ! Alors bien sûr rien de compliqué, je ne vous demanderai rien que je n'aurai expliqué.
ATTENTION : entrez toujours vos programmes sur un émulateur avant de les mettre sur la calto pour vous assurer qu'il n'y ait pas de dangers à les utiliser.
Je vais donc vous demander d'afficher 14 à l'écran (pas $14). Pour voir tout ça, on attendra la pression sur une touche avant de quitter.
Je ne vous demande pas de tout inventer, il y a les romcalls pour ça Servez-vous d'ultimate.inc pour avoir leur adresse.
Allez hophop au boulot !
Vous avez trouvé j'espère ?
Les adresses
Dans le TP précédent, je vous avais dit de ne pas vous occuper des coordonnées car il fallait utiliser des adresses. Hé ben maintenant on va pouvoir !
On va effectivement voir les adresses, leur assigner des trucs et les assigner à d'autres trucs. Toujours plus de trucs !
Assigner un nombre à une adresse
Il est possible d'assigner un nombre à une adresse via les registres 16 bits, mais c'est un peu spécial. En effet, pour assigner un nombre à une adresse, il faut qu'un des registres 16 bits contiennent l'adresse où on veut stocker un nombre ou un registre. On dit que le registre en question est un pointeur, car il contient l'adresse où on veut qu'il se passe des trucs (il la pointe, quoi). En ASM, pour spécifier qu'on utilise un registre comme un pointeur et pas comme un registre, on l'entoure de parenthèses (exemple : ld (de),0).
Et c'est là qu'HL est super utile : alors qu'on ne peut assigner à (bc) et (de) que A, (hl) est carrément pris comme un registre 8 bits ! Ce qui veut dire qu'on peut exercer sur (hl) toutes les opérations qu'on peut exercer sur les autres registres 8 bits ; d'où l'intérêt de ne pas confondre hl et (hl) (n'est-il pas ).
Ce qui fait qu'il n'y a qu'un moyen de stocker un nombre dans une adresse :
[list][*]
Assigner un registre à une adresse
L'assignation d'un registre à une adresse est du même type qu'une utilisation classique d'un registre, avec son lot de difficultés : les registres ont encore un autre nom, la syntaxe n'est pas exactement la même et l'instruction est en 3 ou 4 octets, ce qui est relativement gros.
Donc, une assignation registre à adresse telle que
Les registres pour cette instruction (sachant que seuls A, BC, DE et HL peuvent être assignés à une adresse et vice-versa) :
Pour assigner un registre à une adresse, rien de plus simple : on renseigne le nom du registre et l'adresse. Exemple, pour stocker DE dans ($86D7) (pencol sur 83 ), on va faire :
Attention cependant, on peut également assigner A à (bc) et (de), et n'importe quel registre 8 bits à (hl).
Notez qu'on ne peut pas assigner (hl) à (hl). L'instruction 76 s'appelle Halt, et il n'est même pas dit que je l'aborde dans ce tuto
C'était pas bien compliqué, avouons-le.
Assignation adresse vers registre
Ici c'est comme l'assignation registre vers adresse, sauf que c'est le contraire (je sais pas si je me fais bien comprendre ). C'est la même syntaxe sauf que les registres changent ENCORE de nom.
Donc, pour stocker le contenu de ... tiens ($8599) (cxpage sur 83 ) dans DE, on va faire
On peut aussi stocker (hl) dans n'importe quel registre 8 bits.
En fait, si vous regardez le tableau des assignations registre vers registre, vous verrez que tout se suit mais qu'il y a un trou aux commandes *6 et *E : ce sont les assignations avec (hl), sauf 76 qui est HALT.
Assignation adresse vers adresse
Là encore c'est facile, on peut pas en fait retenez qu'une assignation contenant une adresse doit obligatoirement contenir un registre.
Exercice 2 : le retour
Grâce à ce qu'on sait, on va pouvoir améliorer un peu notre petit TP. On va maintenant choisir où HL devra s'afficher.
Concrètement, je vous demande de créer un programme qui affiche en tant que nombre (toujours avec DispHL = $4507 / $4709 ; utilisez comme adresse currow = $844B / $800C) l'abscisse de ce même nombre. En clair, ce nombre est positionné en (2;5), il doit donc afficher 2.
Je vous demande de jongler entre adresses et registres dans cet exercice.
Ce qu'il y a après le C9 ... cette fois on va l'utiliser !
Vous vous rappelez de ce qu'il y a généralement après le premier C9 (parce qu'on va voir qu'il peut y en avoir plusieurs) ? Des chaînes de caractères en général.
Donc, prenons un code hexa tout ce qu'il y a de plus classique, et ajoutons-lui la chaîne "Hello !" à la fin.
L'espace a pour code $20 et le point d'exclamation $21
Vous pouvez tester ce code si ça vous chante, mais vous ne verrez rien .
Visuellement, ce programme ne fait rien. Concrètement, c'est beaucoup plus que ça.
Un petit tour chez les adresses
Quand on entre un programme hexa avec une chaîne comme celle-ci après le C9, cette chaîne est stockée dans une certaine adresse. Le truc chia embêtant, c'est que cette adresse varie selon la taille même de votre programme.
L'adresse de stockage initiale est $9D93 / $9327. Pour avoir l'adresse où est stockée notre texte, il faut ajouter à $9D93 / $9327 chaque octet du programme avant la chaîne de caractères (on ne compte pas la ou les autres chaînes, et sachant que AsmPrgm vaut 2 octets).
Euuuh je pense que je n'ai pas été très clair
Voici donc comment procéder :
Voici notre code :
On part de $9D93 / $9327, et on ajoute $01 pour chaque groupe de deux caractères avant la chaîne (avec AsmPrgm = 2 octets). Ce qui nous fait $9D93 $03 = $9D96
Donc pour charger l'adresse du texte dans un registre (16 bits uniquement, c'est une adresse rappelons-le ; mais en général on utilise HL) il y a un groooos piège :On utilise le nom d'un registre comme si l'adresse du texte était une valeur normale.
En clair : si je vous avais dit "stockez la valeur de l'adresse $9D99 dans HL" (ben oui, $9D99 : il faut compter la commande de stockage elle-même ; elle vaut trois octets), sachant ce que vous savez sur les adresses vous m'auriez mis :
Sur 82 stats, c'est pareil, sauf que comme je l'ai dit on commence à $9327 et qu'il n'y a pas de AsmPrgm.
Bon, toujours est-il que maintenant que vous connaissez la marche à suivre, on va enfin pouvoir faire notre Hello world !
Le tant espéré Hello world
Comme ici c'est un peu plus compliqué que d'habitude, on va le faire ensemble ce Hello world.
Prenons donc un code de base :
Nous avons donc notre chaîne de caractères. Déjà pour faire beau on va effacer l'écran avec ClrLCDFull ($4540 / $4755), puis comme on veut afficher notre chaîne au milieu de l'écran et en minuscules (si si, on veut , avec vPuts et tout) on va stocker les coordonnées ($1A;$1A) (soit 26;26) dans DE et stocker DE dans penCol (situé à l'adresse $86D7 / $8252) :
Maintenant, on appelle vPuts ($4561 / $4781) pour écrire le texte à l'adresse pointée par HL en petits caractères :
Maintenant, vous savez comment assigner cette chaîne. Alors faites-le sachant que si vous vous trompez, tant que vous mettez bien 21 au début ça ne fera qu'afficher une valeur fausse.
Rappelez-vous que la valeur de départ est $9D93 / $9327, et qu'il faut ajouter $01 à chaque octet du programme avant le C9, en incluant le C9 lui-même ainsi que la commande d'assignation à HL (mesurant 3 octets).
On a donc notre code final :
Entrez ce code sur votre calculatrice (je l'ai testé personnellement sur calculatrice, il marche), si vous avez peur de vous tromper entrez-le sur émulateur, mais testez-le !
Et vous obtenez :
[Vous devez être inscrit et connecté pour voir cette image]
Magnifique non ?
Les tests, les sauts, les sauts conditonnels et les getkey's
Les tests
Tous les programmeurs connaissent cette instruction, celle qui est apprise dès les débuts, je parle bien sûr de l'instruction IF. Eeeet malheureusement, cette commande n'existe pas en hexa, et pas plus qu'en ASM d'ailleurs. Mais alors me direz-vous, comment tester la valeur de ceci ou cela ?
Pour répondre à cette question, un petit cours d'ASM s'impose.
En ASM, pour effectuer un test, la solution la plus répandue s'appelle CP. Non, rien à voir avec les Classes Préparatoires, mais bien avec les tests.
Cette fonction est un peu spéciale car elle simule une soustraction sur A, car je vous rappelle qu'on ne peut effectuer des opérations que sur l'Accumulateur.
Comment ça elle simule, et bien en fait cette instruction ne modifie pas la valeur de A, d'une part, et modifie quand même les flags liés à A, d'autre part. Je m'explique.
Les flags sont des bits (donc soit 0 soit 1) décrivant chacun une action ou un état. Les flags les plus utilisés sont ceux décrivant A :
Si vous ne deviez retenir que deux de ces flags, retenez C et Z, ce sont à ma connaissance les plus utiles en le plus de circonstances.
Revenons à notre instruction CP. Je disais tout à l'heure qu'elle simulait une soustraction (on parle de soustraction virtuelle). En réalité cette commande ne modifie en aucun cas la valeur d'aucun registre, mais met à jour tous les flags de A. Ainsi, prenons ce code :
Après la première instruction, on a A = $04. Donc si on fait un résumé des flags :
Au vu de ces flags, on peut déduire que si Z est activé, tous les autres sont désactivés et si S est activé, C l'est aussi.
C'est fini pour la partie ASM, voyons maintenant l'hexa.
En hexa, CP se traduit par FE, et cette commande FE est la réplique exacte de CP :
ATTENTION ! Ne confondez jamais FE, qui exerce une soustraction virtuelle avec EF, qui appelle une romcall !
Les flags de A sont les mêmes en hexa qu'en ASM, c'est juste que comme tout registre ou adresse en hexa, ils ne s'appellent pas pareil et change de nom selon le contexte
Les sauts
Sortons un peu du contexte de la condition en voyant les sauts. Bien sûr, c'est uniquement pour y replonger ensuite avec plus de ressources
Le principe du saut en programmation est qu'à un certain endroit d'un programme, on a une instruction qui dit "va directement à l'instruction située à l'adresse xxx sans exécuter ce qui la sépare de moi". C'est exactement le principe de Lbl et Goto en basic (et comme dans un bon paquet de langages d'ailleurs).
En ASM comme en hexa, il y a plusieurs fonctions de sauts (je parle des non conditionnels, on verra les conditionnels juste après). Les plus répandues sont JR et JP.
La différence entre ces deux instructions, hormis le fait que JR prend deux octet et JP trois, est la portée de leur saut : alors que JR peut sauter 128 = $80 octets en avant ou en arrière dans le programme, JP peut sauter 32 kilo octets = 32768 octets = $8000 en avant ou en arrière, c'est à dire toute la RAM en fait
On dit que JR exerce un saut relatif et JP un saut absolu, vous allez comprendre pourquoi.
La syntaxe de ces deux commandes est en ASM :
MAIS heureusement, pour la commande JR en hexa, commande qui s'appelle 18, retenez-le, on ne doit pas renseigner l'adresse exacte ! On doit juste renseigner de combien d'octets avancer ou reculer. C'est l'adresse relative, car elle dépend du point de départ.
Mais comment on sait si on avance ou on recule ?
Vous vous rappelez que JR saute de 128 octets en avant ou en arrière ? Et quelle est la valeur maximale qu'on peut représenter avec 8 bits ?
En fait, le sens du saut va dépendre de la valeur que vous passez en argument. Si la valeur est entre $01 et $7F, le saut va d'autant d'octets vers l'avant. Si la valeur passée en argument va de $80 à $FF, le programme recule de $100 - [valeur] octets. Exemple :
Comme pour charger du texte, pour connaître l'éloignement en octets de votre instruction où sauter, la meilleure méthode reste encore de compter les groupes de deux caractères. Re-exemple :
Notez que l'instruction 18xx est comptée dans le nombre d'octets à sauter. Vous aurez donc compris que
Faites très attention à ne pas débouler au milieu d'une instruction, ça dérèglerait complètement le programme, d'où l'intérêt de structurer son code avec une seule instruction par ligne pour mieux se repérer.
Pour l'instruction JP, en ASM sa syntaxe ne change pas mais en hexa, cette fois il faut renseigner l'adresse exacte (donc 16 bits, théoriquement de $0000 à $FFFF mais notre programme commence à $9D93 / $9327) du point de reprise. On parle d'adresse absolue car on veut l'adresse exacte en dur de l'endroit où sauter. C'est d'ailleurs très dangereux si vous ne savez pas par coeur où votre programme commence (pis de toute façon en hexa c'est rare d'avoir à sauter plus de 128 octets ).
La commande JP s'écrit donc en hexadécimal C3 et prend en arguments une valeur 16 bits qui ne peut pas être un registre, ça doit être une adresse en dur, toujours en sachant que votre programme débute en $9D93 / $9327 (ce qui fait 3 octets, un de plus que JR).
Les sauts conditionnels
Retour aux conditions donc, et cette fois nous allons réellement pouvoir traduire l'instruction If en hexa (et non pas de Else ici ) !
Pour réaliser un saut conditionnel, le principe est de tester la valeur d'un flag puis de réaliser un saut (absolu ou relatif) si le flag testé est activé. Dans notre cas de traduction de If, on utilisera un saut conditionnel juste après une commande CP (ou FE en hexa, souvenez-vous). Nous allons donc tester les flags de A.
Attends ça veut dire qu'on ne peut pas tester si le bit est désactivé ?
Oui et non. En réalité, chaque flag de A est "dédoublé" pendant un test en une version "inversée". Ainsi, les flags classiques de A dérivent en :
Les instructions de sauts conditionnels les plus répandues sont ... JR et JP. Ah tiens, comme on se retrouve
En fait, en ASM il peut y avoir deux notations à ces commandes :
Par contre, ATTENTION, EXCEPTION : avec JR, on ne peut pas tester l'état de PO, PE, P ni M. En ASM ça fera une erreur de compilation et en hexa la commande n'existe carrément pas
Justement, à propos de ça : à chaque flag à tester avec JR ou JP correspond une commande. Par exemple, le saut relatif obligatoire de $2D octets en avant se notera :
Voici donc une liste des dérivées de JR :
Vous remarquerez qu'il y a une commande tous les 8 bits, car par exemple $30 (test de NC) - $28 (test de Z) = $08. Ça prouve bien qu'il y a une part de logique dans ce que je vous apprends .
Et voici celles de JP :
Vous remarquerez que l'adresse du saut obligatoire suis également l'ordre des sauts conditionnels. Vous remarquerez également que JP peut tester deux fois plus de flags que JR. Il est effectivement la seule solution pour tester la parité (pair / impair), et une solution plus sûre pour tester le signe (vous pouvez très bien tester le signe avec C (Carry), qui s'active si A est plus petit que 0, mais faites attention car il s'active aussi s'il est plus grand que 255).
Grâce à ça, on peut traduire le code :
Explicons ce code :
Dis comme ça, ça a peut-être l'air super dur, mais en fait c'est tout bête : on soustrait virtuellement, on teste un flag, on saute au bon endroit et on re-saute pour éviter le code qui aurait été exécuté le cas échéant.
Un cas d'application concret : le getkey
Vous devez être un peu sceptiques quand aux possibilités d'application de cette méthode. Et bien je vais vous en apprendre une bien bonne : la romcall getkey ($4972 / $4CFE) attend une touche et stocke sa valeur dans A. Et rappelez-moi, c'est sur quel registre qu'agit CP déjà ? Sur A !
On peut donc soustraire virtuellement à A la valeur d'une touche (que vous pourrez trouver dans ultimate.inc et ti83asm.inc, leur nom commence tous par k), on teste Z pour voir si A correspond et on agit en conséquence !
En général, le nom des touches dans les includes est un k suivi de ce qui est écrit sur la touche (en Anglais !). Par exemple la touche Y= (ou f(x) pour les Ti plus récentes) s'appelle kyequ. Autre exemple : la flèche du haut s'appelle kup. Notez qu'il existe kmem (le menu accessible par [2nd] [ ]) et une touche pour tous les menus accessibles par [2nd]. Notez aussi qu'il est impossible de détecter [2nd] ni [alpha] (pour le moment ).
Les getkey's : application
Non non on ne va pas coder une app , mais VOUS allez plutôt écrire un programme à l'aide de ce que j'espère vous avoir appris dans ce chapitre.
Vous allez donc écrire un programme complet (avec le bon format et tout), qu'on peut exécuter sur calto sans danger (toujours préciser ) et qui attend une touche : si la touche 5 est appuyée, le programme attend une nouvelle touche, et si cette touche est la flèche droite, il quitte. Si à une quelconque étape du programme la mauvaise touche est pressée, il repart au début.
Voilà, vous avez parfaitement le niveau pour faire des "vrais" programmes sympas, qui réagissent aux touches et tout ! Rappelez-vous qu'il y a plein de romcalls, dont des romcalls graphiques, qui utilisent seulement les registres comme arguments, et sont de ce fait facile à utiliser en hexa : on assigne valeur à registre, un petit coup de EF ou CD et hop ! On a un beau truc
Les boucles
En Ti-Basic (et dans tous les autres langages de programmation à part l'ASM) existe le concept de boucles. Ces boucles peuvent s'appeler For(), While(), Repeat() ou même DS<() ou n'importe quoi d'autre, leur utilité sera toujours de répéter des actions tant qu'une condition est vraie (ou fausse).
En ASM et en hexa, l'instruction qui se rapproche le plus d'une boucle a un nom barbare et ressemble de très près aux boucles For() et DS<(), j'ai nommé DJNZ. Aaaah ben oui je vous avais prévenu, c'est un nom barbare ! Vous comprendrez peut-être son utilité si je vous dit ce qu'elle signifie : Decrement and Jump if Non-Zero. Si vous voyez toujours pas, vu que cette phrase ne veut rien dire en Français, je vous donne carrément son mode de fonctionnement.
Cette instruction s'écrit en ASM de la manière suivante :
Donc, DJNZ va décrémenter B (lui soustraire 1, pas virtuellement cette fois) et sauter à l'adresse spécifiée si B est différent de 0. On comprend tout de suite mieux la signification du nom là hein ?
Cette instruction DJNZ est l'équivalent ASM de :
Donc en gros, pour faire un truc 5 fois en ASM, on écrira :
Donc, en hexa DJNZ s'appelle 10. Sympa, facile à retenir et tout . La voici donc utilisée :
ATTENTION ! Veillez bien à ne pas modifier la valeur de B pendant l'utilisation de DJNZ, car cela aboutirai à une boucle infinie, B étant modifiée à chaque tour de boucle et remise à sa valeur initiale !
Tout le tuto ne tient pas dans un seul message, donc voyez la suite ici : [Vous devez être inscrit et connecté pour voir ce lien]
J'ai demandé il y a un peu de temps s'il existait un tutoriel d'hexadécimal, pour pouvoir programmer on-calc en autre chose qu'en Ti-basic. On m'a dit que ça ne devait pas exister, vu la complexité du truc. Alors comme je suis maso ( ) j'ai décidé d'apprendre l'hexa tout seul (et là j'ai compris pourquoi y'a pas de tutos ).
Toujours est-il que si vous voulez programmer on-calc, que vous ne comptez pas vous relire un jour et que vous aimez les challenges, vous pouvez programmer en hexadécimal .
Donc ben je me suis dit "tiens ben je m'en sors pas trop mal, j'ai qu'à en faire profiter les gens ça leur évitera de souffrir inutilement. Alors ben voilà, je vous dit ce que je sais et j'édite au fur et à mesure
Ah oui aussi : ce dont je vais parler ici c'est de l'hexadécimal pour Ti-83 , 83 SE, 84 et 84 SE. N'essayez pas de suivre avec une autre calto, tout ce que vous allez faire c'est la ruiner un maximum.
J'ai modifié l'ensemble du tuto pour qu'il soit compatible 82 stats.
L'hexa des deux calculatrices est le même de toute façon, à part quelques petits trucs, c'est pour ça que ça mérite des précisions
De plus, je pars du fait que vous "avez déjà entendu parler de l'ASM". Donc faut savoir ce qu'est une romcalls, un registre, une variable et une adresse en gros.
ATTENTION : CE QUE JE VAIS VOUS APPRENDRE EST EXCEPTIONNELLEMENT DANGEREUX. TOUS LES EXEMPLES QUE JE PRÉSENTERAI AURONT ÉTÉ PRÉALABLEMENT TESTÉS SUR ÉMULATEUR. TOUT DOMMAGE À VOTRE CALCULATRICE DÛE À UNE FAUTE DE COPIE NE SAURA M'ÊTRE IMPUTÉE.
Introduction : registres, variables, adresses, romcalls et autres joyeusetés
Pour ceux qui ne connaissent pas encore l'ASM, vous ne comprendrez sûrement pas le tuto dans son intégralité. C'est pourquoi je vais vous expliquer rapidement les rudiments de ce langage (et donc de l'hexadécimal).
Les registres
Vous vous rappelez de vos variables prédéfinies A, B, C ... Z, thêta en Ti-Basic ? Oui ? Parfait, oubliez-les. Les variables en ASM n'ont absolument rien à voir avec celles que vous connaissiez jusqu'à présent.
En ASM, d'une part les "variables" dont je parle actuellement ne sont pas de vraies variables, les "variables" en ASM c'est autre chose.
En ASM et en hexadécimal on va parler de registres. Ce sont des emplacements mémoires (variables selon le contexte) qui vont servir à contenir uniquement des nombres. En ASM comme en hexa, tout se fait avec des nombres.
Il existe des registres 8 bits (c'est-à-dire qui contient un chiffre entre 0 et 255 en décimal, $FF en hexadécimal et 111111 en binaire) appelés A, B, C, D, E, F (qui n'existe pas en hexadécimal et qu'on utilise pas directement en ASM), H et L. On peut les utiliser comme simples zones où stocker des données (à part F).
A est un peu spécial : c'est l'accumulateur. C'est sur lui qu'on va effectuer des opérations. Par exemple, il est impossible d'ajouter une valeur à B, on doit obligatoirement passer par A.
Il existe également des registres 16 bits (qui contiennent un nombre entre 0 et 65535 en décimal, $FFFF en hexa et 11111111111111 en binaire). Ce sont en fait des combinaisons de registres 8 bits : AF (modifié au même titre que F), BC, DE et HL.
Les 8 bits et 16 bits correspondent : si vous modifiez H, alors HL lui aussi va être modifié, dans sa partie "du haut" : en effet, si on met séparément :
- Code:
H = $07
L = $12
Les adresses
Ce sont les "zones de mémoire" dont je parlais. Elles sont définies en général par un chiffre hexa (toujours de 16 bits, donc entre $0000 et $FFFF) et sont entre parenthèses (en ASM ; en hexa c'est plus compliqué). Elles vont, quand on les appelle, orienter le programme vers la valeur situé à l'adresse appelé. Par exemple, si B se situe à $0075 et qu'on appelle H = ($0075), alors H vaudra B.
Elles sont un peu compliquées à utiliser en hexa, donc on les verra plus tard. Toujours est-il qu'on peut leur assigner n'importe quelle valeur, mais toujours à travers A ou un registre 16 bits.
Les romcalls
Ce sont les équivalents des fonctions en Ti-Basic. Par exemple, ClrHome en Ti-Basic s'appelle ClrLCDFull en ASM et $4540 en hexa. Pour appeler une romcall en ASM, on entre :
- Code:
bcall(nom_de_la_romcall_ou_adresse_hexa_de_la_romcall)
Les romcalls "ne prennent jamais d'arguments". On serait tentés de dire ça sachant qu'en ASM la fonction d'appel d'une romcall ne laisse pas de place pour des arguments.
En réalité, une romcall utilise comme arguments registres ou adresses, auxquels on aura assigné la bonne valeur au préalable. Bien sûr, une romcall n'utilise pas systématiquement tous les registres.
Les variables
En ASM, les variables sont simplement des noms assignés à des adresses pour faciliter leur utilisation. En hexadécimal, les variables n'existent pas vu qu'on ne manipule que des chiffres. Je ne m'étendrai donc pas dessus.
Les opérateurs
La notion d'opérateur est compliquée en ASM. Ce n'est pas une romcall, pas un registre, pas une adresse. Pour vous donner un exemple, l'opérateur ld prend en arguments deux registres, et stocke la valeur du deuxième dans le premier :
- Code:
ld D,A
stocke la valeur de A dans D
Un autre exemple ; l'opérateur ADD prend deux arguments : le registre A (je me demande encore pourquoi il est obligatoire de le préciser) et une valeur à lui ajouter (registre, adresse, chiffre ...).
- Code:
ld A,$07
A vaut $07
ADD A,$02
A vaut maintenant $09
Comme je disais, les opérateurs sont nombreux et compliqués, on en parlera donc plus tard.
Bon, maintenant nous voilà prêts à attaquer l'hexadécimal !
Créer un programme hexadécimal
Sur Ti-83
Pour créer un programme hexa sur une des calculatrices ci-dessus (les autres fichez le camp ), c'est au moins aussi simple que créer un programme Ti-basic : on va dans [prgm] NOUVEAU et on tape le nom de son programme.
Par contre, si on en reste là la calto va réellement croire que c'est un programme Ti-basic. Donc on va signaler notre identité en ajoutant le token (ou mot-clé) AsmPrgm (uniquement via le catalogue), comme ça elle est bien mise au courant.
Sinon à part ça, je vous dit tout de suite comment exécuter un programme hexa, c'est pas beaucoup plus compliqué. Pour info, ça se lance exactement de la même manière qu'un programme ASM :
- Code:
Asm(prgmXXXXXXXX
Enfin non, en réalité y'a deux façons :
- La commande précédemment décrite, ou
- En compilant le programme avant de le lancer
Pour compiler un programme hexa, on a une commande tout prête appelée AsmComp() (toujours via le catalogue) qui prend en premier argument le programme à compiler et en deuxième argument le nom du fichier de sortie (qui ne doit évidemment pas déjà exister sous peine d'une ERROR:DUPLICATE). Le résultat sera un programme deux fois plus léger et rapide à lancer avec la première méthode. Un exemple pour illustrer le tout et on s'y met :
- Code:
Première méthode :
Asm(prgmHEXA
Deuxième méthode :
AsmComp(prgmHEXA,prgmEXECUTER
Asm(prgmEXECUTER
Pour 82 stats
C'est pareil que pour 83 , mis à part le format du fichier. Alors que sur 83 on a :
- Code:
:AsmPrgm
:... code
- Code:
:... code
:End
:0000
:End
À peine plus long, mais attention à pas vous tromper, ça ferait planter la calto.
Sur 82 stats, il n'y a pas de commande Asm( ), mais rassurez-vous on peut quand même lancer des programmes ASM :
- Code:
Send(9prgmHEX
Et pour les 82 stats.fr :
Envoi(9prgmHEX
Par contre, impossible de compiler un code hexa sur 82 stats.
Le header en hexadécimal
Si vous connaissez l'ASM (je vais faire comme si), vous vous rappelerez sûrement du header, à écrire au début de chaque programme ASM. Ce header ressemblait plus ou moins à ça :
- Code:
.org $9D93
.db $BB,$6D
; ici les .equ et autres #define
; programme
Ici rien de tout cela : comme en hexadécimal on n'utilise pas de lettres (ben oui A B C D E F c'est des chiffres je vous rappelle ) on n'a pas à s'embarrasser de conventions, de casse ou de quoi que ce soit.
Ce qui fait que notre beau header pimpant se résume en :
- Code:
:AsmPrgm
AsmPrgm est un token qui indique à la calto que le programme est en hexa (un peu comme le End:0000:End des 82 stats). Il va être remplacé à la compilation par $BB6D.
Ce BB6D, d'où sort-il ? Et bien c'est simple : c'est un token. Si si promis.
En fait le token AsmPrgm a pour code hexa $BB6C. C'est le token commençant un programme hexa (ou ASM précompilé). Et le token ayant pour code $BB6D est le token AsmCmp. Vous ne le verrez jamais puisque par défaut la calculatrice dit que chaque programme commençant par ce token est de l'ASM compilé et doit être inaccessible à l'édition. C'est pour ça qu'on ne peut pas éditer certains programmes, parce qu'ils commencent par ce token.
Structurer son code hexadécimal
L'avantage avec le code hexadécimal, c'est que comme justement il est en hexadécimal, il ne comprend pas les sauts de ligne tant qu'ils ne coupent pas un octet en deux (on va voir ça). Par contre, il comprend les espaces, et il saura bien vous le dire via une ERROR:SYNTAX.
ATTENTION : si votre code hexa comporte une erreur détectée par la calto, appuyer sur Goto ne sert à rien, ça vous renverra à la fin de la commande Asm().
Donc je viens de dire que la calto n'est pas gênée par les sauts de ligne tant qu'ils ne coupent pas un octet en deux. Et c'est vrai :P
Les "commandes" en hexadécimal (on ne peut pas vraiment les appeler comme ça mais bon) s'écriront toujours tout le temps de la même manière : des groupes de deux chiffres hexadécimaux. Sachant qu'un chiffre hexa traduit 4 bits et forme ce qu'on appelle un quartet, deux chiffres hexa traduisent 8 bits en formant un octet. C'est la position des bits qui va donner le token à interpréter.
Donc disais-je, si dans un accès de frustration et de rage contre votre calculatrice vous insérez un saut de ligne entre deux quartets qui correspondent, elle va pas être d'accord et vous le fera savoir via une ERROR:SYNTAX !
Exemple :
- Code:
:936103
:7AC8D5EFBA
Ça ça marche
:19473
:93DEFA8
Ça non
En fait c'est simple, si vous voyez une ligne comprenant un nombre impair de chiffres, c'est pas bon.
Aussi, en ASM les programmes finissent tous par RET (l'instruction qui finit le programme). Ben là c'est plus RET c'est C9. Donc si vous ne mettez pas C9 à la fin de chaque programme, ça risque de bousiller votre calto en moins de temps qu'il n'en faut pour le dire. On a donc un code minimal qui ne fait rien :
- Code:
:AsmPrgm
:C9
Ou même
:AsmPrgmC9
Dernière chose, au niveau de la lisibilité (si lisibilité il y a ), essayez au maximum de donner une structure cohérente à votre code. C'est à dire, mettez une instruction par ligne, pas deux, pas trois et encore moins une moitié d'instruction. Parce que oui, on peut mettre des "moitiés" d'instruction. Donc en gros pour mettre $54D1 dans DE et $41E6 dans HL faites ça :
- Code:
:11D154
:21E641
Et pas ça :
- Code:
:11D15421E641
- Code:
:11D1
:5421
:E641
Bon, ben cette fois on est paré, on peut y aller ! À l'assauuuuut !!!
Les registres et l'assignation en hexadécimal
Aïe ...
À partir d'ici la vraie galère commence.
Après des heures de dur labeur, j'ai enfin trouvé toutes les adresses des registres !!!!! [Vous devez être inscrit et connecté pour voir cette image]
Commençons avec les registres. Ben c'est les mêmes qu'en ASM c'est juste qu'ils s'appellent pas pareil
Par exemple, en hexadécimal, hl s'appelle $21. Et encore, pas tout le temps.
Ah oui non parce qu'en plus de faire la même chose MAIS de s'appeler pas pareil, faut EN PLUS qu'ils jouent les schyzophrènes à changer de nom selon le contexte par exemple, si vous voulez mettre une valeur dans DE il va s'appeler $11, mais si vous voulez mettre DE dans un autre registre il va s'appeler autrement !!! Si c'est pas juste pour faire ch*er les gens ça !
L'assignation classique : valeur hexadécimale vers registre
C'est le cas le plus courant, qui correspond à assigner une valeur hexadécimale (on fait de l'hexa je rappelle [Vous devez être inscrit et connecté pour voir cette image] ) à un registre. En ASM, on fait comme ça :
- Code:
ld a,$07 ; maintenant, le registre a contient $07
- A s'appelle $3E
- B s'appelle $06
- C s'appelle $0E
- D s'appelle $16
- E s'appelle $1E
- F s'appelle pas
- H s'appelle $26
- L s'appelle $2E
- AF s'appelle pas non plus
- BC s'appelle $01
- DE s'appelle $11
- HL s'appelle $21
Oui, en fait AF et F n'existent pas, puisque les flags sont gérés directement en hexadécimal (on n'utilise pas F).
On remarque que les adresses de tous les registres 8 bits (sauf A) peuvent être devinés dès qu'on connaît celle de B ($06). En effet, chacun de ces registres étant de 8 bits, par exemple pour trouver C on a juste à faire B $08, ce qui donne $0E, et ainsi de suite. C'est pareil pour les registres 16 bits à partir de BC ($01) auquel par exemple pour trouver DE on ajoute 16, soit $10. Donc, DE est bien situé à $11.
Alors c'est sûr que niveau optimisation c'est du jamais vu mais je vous dis pas combien j'ai galéré pour comprendre la signification de ces deux octets qui ressemblent à rien !
Donc, pour assigner $42 (donc 66) à E, on fera :
- Code:
1E42
Dans le même esprit, ici on assigne $3D94 à HL :
- Code:
21943D
- Spoiler:
- Si on regarde le code, on voit qu'on assigne à HL non pas $3D94 mais $943D ! En effet, on doit inverser les octets de toute valeur 16 bits pour l'utiliser correctement.
L'assignation registre vers registre
Accrochez-vous, là ça devient vraiment compliqué.
Les registres 8 bits
Pour assigner un registre à un autre registre, la théorie est très simple et l'application très compliquée : en effet, cette commande en ASM :
- Code:
ld a,b
- Code:
78
Donc disais-je, pour assigner un registre à un autre, on doit spécifier le nom du registre cible avec un premier quartet, et le nom du registre source avec le deuxième quartet.
MAIS si c'était juste ça ça serait trop facile ! Ah ben non mais c'est pas marrant comme ça !
Donc en fait, le nom du registre source varie en fonction du registre cible. En Français compréhensible [Vous devez être inscrit et connecté pour voir cette image] , si on veut faire
- Code:
ld a,b
- Code:
ld d,b
Mais le PIRE, c'est qu'il y a des registres cibles qui s'appellent pareil ! Et là croyez-moi c'est vraiment le ouaï quand on se met à utiliser beaucoup de registres.
Pour commencer, les registres sources :
- A s'appelle 7. Heureusement, c'est le seul (pour l'instant )
- B s'appelle 4
- C s'appelle 4 aussi
- D s'appelle 5
- E s'appelle aussi 5
- H s'appelle 6
- Devinez quoi ? L s'appelle 6
Mais alors vous allez me dire, comment lors d'une assignation différencier B et C ? D et E ? H et L ? Et ben c'est simple non pas du tout en fait [Vous devez être inscrit et connecté pour voir cette image] : en fonction du registre source. Heureusement, vous n'avez que deux registres source à connaître :
- Si le registre cible est B,D ou H, A s'appelle 7. Sinon, si la cible est C,E ou L, A s'appelle F
- Si le registre cible est B (pour les autres registres), D ou H, B s'appelle 0. Sinon, si la cible est A, C, E ou L, B s'appelle 8
À partir de B, vous pouvez calculer C, D, E, H et L simplement en ajoutant $01.
ATTENTION : faites très attention au registre cible ! Je ne sais pas ce que ça va donner si pour assigner C à D vous faites
- Code:
59
- Code:
51
Voici un tableau pour résumer tout ça :
Cible / Source | A | B | C | D | E | H | L |
A | X | 78 | 79 | 7A | 7B | 7C | 7D |
B | 47 | X | 41 | 42 | 43 | 44 | 45 |
C | 4F | 48 | X | 4A | 4B | 4C | 4D |
D | 57 | 50 | 51 | X | 53 | 54 | 55 |
E | 5F | 58 | 59 | 5A | X | 5C | 5D |
H | 67 | 60 | 61 | 62 | 63 | X | 65 |
L | 6F | 68 | 69 | 6A | 6B | 6C | X |
Vous êtes toujours vivants ? [Vous devez être inscrit et connecté pour voir cette image] Alors faisons un petit exercice pour que ça soit définitivement clair dans votre tête.
En hexadécimal, faites un programme complet (qu'on pourrait lancer sur la calto) qui assigne :
- D à H
- C à A
- L à B
- A à L
ATTENTION : on écrit d'abord la cible et ensuite la source, comme pour la commande ld !
- Correction:
J'avoue que c'est un peu hard à retenir au début, mais vous verrez, on s'y fait.- Code:
:AsmPrgm
:62
:79
:45
:6F
:C9
En fait, ce n'est pas par pur sadisme ou par haine contre les programmeurs qu'on utilise ce système. C'est parce qu'on a vu ici les registres 8 bits, et "bizarrement", vous voyez que les registres cibles vont 2 par 2 ... et que les sources s'étendent toujours sur 8 bits ... ah tiens
Et si on y regarde un peu plus près, sur A par exemple : selon la cible, il vaut 7 ou F ...
Mais attends $F - $7 = $8 !!!!
Et oui, il y a une véritable raison à ce système. Chaque registre prend 8 bits, mais comme il n'y a aucun espace de mémoire libre, on est obligé de mettre deux registres 8 bits dans un seul emplacement 16 bits.
CQFD.
Les registres 16 bits
Avec les registres 16 bits, c'est très simple : on fait pas . Ben oui carrément, on ne peut pas stocker des registres (8 ou 16 bits) dans un registre 16 bits. Que des adresses, on verra ça beaucoup plus tard.
Les romcalls
Là c'est bon, j'ai trouvé tout ce qu'il fallait, ce sera un des rares chapitres complets Pour appeler une romcall en ASM, vous utilisiez :
- Code:
bcall(xxxx)
Qui est en fait :
rst 28h
.dw xxxx
Hé ben bonne nouvelle : en hexa c'est pareil !
- rst 28h s'appelle EF
- On enlève les parenthèses
- On inverse les octets de la romcall
Sur 82 stats EF ne sert pas à ça ! Utilisez toujours CD (call) à la place !
Aaaaah ! Enfin un truc simple !
Donc récapitulons, sachant qu'en ASM pour effacer l'écran on fait :
- Code:
bcall($4540)
Sur 82 stats :
call $4755
En hexa on fait ..? Allez devinez !
- Solution:
- Code:
:EF4045
Pour 82 stats :
CD5547
Pour les romcalls qui utilisent des arguments, c'est comme en ASM : on a juste à assigner la bonne valeur au bon registre et appeler la romcall qui va l'utiliser paisiblement. Vous plaignez pas, pour une fois que y'a un truc facile
Par contre il va y avoir un autre gros problème, c'est au niveau des romcalls, pour savoir où elles se situent, parce que je pense pas que ça vous éclate de retenir des adresses comme ça
C'est pourquoi je vous conseille de télécharger le fichier include ultimate.inc qui contient les adresses de tellement de trucs et de machins que vous allez faire un overflow si vous essayez de tous les compter
Pour Ti-82 stats, utilisez ti83asm.inc, car les adresses des romcalls varient de la 82 stats à la 83 .
Et donc grâce à ces fichiers, vous aurez toutes les adresses de n'importe quoi sous la main.
Après le C9 ...
En ASM, y'a plein de trucs après le RET. Par exemple les .db ou les autres labels.
Ben en hexa c'est plus ou moins la même chose, on a l'instruction C9 puis encore tout plein de trucs.
Alors je ne vous parlerai ici que du cas de la chaîne de caractère parce que je connais que celui-là, donc m'en voulez pas trop hein
En ASM, pour rajouter une chaîne à un label vous mettiez un .db non ? Ben pas en hexa. En hexa pour les chaînes comme ça c'est l'anarchie totale, on écrit C9, on saute une ligne pour faire bô et on balance la chaîne comme ça sans rien. Chaîne bien sûr codée en hexa, à partir de A = 65 = $41 et on ajoute $1 pour monter d'une lettre dans l'alphabet.
- Code:
:AsmPrgm
; programme
:
:C9
:414243444500
Je ne sais pas encore comment utiliser ces chaînes, mais promis je saurai bientôt !
Mini-TP surprise
Parce que je pense vous avoir appris assez de trucs pour pouvoir les mettres en oeuvre, je vous demande maintenant de créer votre premier programme entièrement hexadécimal ! Alors bien sûr rien de compliqué, je ne vous demanderai rien que je n'aurai expliqué.
ATTENTION : entrez toujours vos programmes sur un émulateur avant de les mettre sur la calto pour vous assurer qu'il n'y ait pas de dangers à les utiliser.
Je vais donc vous demander d'afficher 14 à l'écran (pas $14). Pour voir tout ça, on attendra la pression sur une touche avant de quitter.
Je ne vous demande pas de tout inventer, il y a les romcalls pour ça Servez-vous d'ultimate.inc pour avoir leur adresse.
Allez hophop au boulot !
- Indice:
- Il n'y a pas 36 manières d'afficher des chiffres : utilisez HL et la romcall DispHL (83 : $4507; 82 stats : $4709). Cette romcall utilise des coordonnées, mais comme il faut utiliser les adresses (pour curRow) laissez tomber les coordonnées pour l'instant. N'oubliez pas que la valeur de HL est en hexa, alors que celle affichée est en décimal !
De plus, pour attendre une touche, utilisez _getKey (83 : $4972; 82 stats : $4CFE
Vous avez trouvé j'espère ?
- Correction:
- La correction n'est pas réellement difficile :
Ti-83- Code:
:AsmPrgm
:210E00
:EF0745
:EF7249
:C9
- Code:
210E00
CD0947
CDFE4C
C9
End
0000
End
EF0745 / CD0947 appelle DispHL avec les coordonnées courantes. Il va donc afficher $000E, soit 14.
EF7249 / CDFE4C appelle getkey. Le programme va donc attendre qu'on appuie sur une touche.
C9 termine le programme.
C'est là qu'on voit la vraie puissance de l'hexadécimal : les programmes sont beaucoup plus courts et plus rapides que l'ASM, mais en contrepartie beaucoup moins compréhensibles.
Les adresses
Dans le TP précédent, je vous avais dit de ne pas vous occuper des coordonnées car il fallait utiliser des adresses. Hé ben maintenant on va pouvoir !
On va effectivement voir les adresses, leur assigner des trucs et les assigner à d'autres trucs. Toujours plus de trucs !
Assigner un nombre à une adresse
Il est possible d'assigner un nombre à une adresse via les registres 16 bits, mais c'est un peu spécial. En effet, pour assigner un nombre à une adresse, il faut qu'un des registres 16 bits contiennent l'adresse où on veut stocker un nombre ou un registre. On dit que le registre en question est un pointeur, car il contient l'adresse où on veut qu'il se passe des trucs (il la pointe, quoi). En ASM, pour spécifier qu'on utilise un registre comme un pointeur et pas comme un registre, on l'entoure de parenthèses (exemple : ld (de),0).
Et c'est là qu'HL est super utile : alors qu'on ne peut assigner à (bc) et (de) que A, (hl) est carrément pris comme un registre 8 bits ! Ce qui veut dire qu'on peut exercer sur (hl) toutes les opérations qu'on peut exercer sur les autres registres 8 bits ; d'où l'intérêt de ne pas confondre hl et (hl) (n'est-il pas ).
Ce qui fait qu'il n'y a qu'un moyen de stocker un nombre dans une adresse :
- ld (hl),** → 26**
[list][*]
Assigner un registre à une adresse
L'assignation d'un registre à une adresse est du même type qu'une utilisation classique d'un registre, avec son lot de difficultés : les registres ont encore un autre nom, la syntaxe n'est pas exactement la même et l'instruction est en 3 ou 4 octets, ce qui est relativement gros.
Donc, une assignation registre à adresse telle que
- Code:
ld ($844B),bc
; La valeur de BC va à l'adresse $844B
- Code:
ED434B84
Les registres pour cette instruction (sachant que seuls A, BC, DE et HL peuvent être assignés à une adresse et vice-versa) :
- A s'appelle 32
- BC s'appelle ED43
- DE s'appelle ED53
- HL s'appelle 22
Pour assigner un registre à une adresse, rien de plus simple : on renseigne le nom du registre et l'adresse. Exemple, pour stocker DE dans ($86D7) (pencol sur 83 ), on va faire :
- Code:
ED53D786
- Code:
32D886
Attention cependant, on peut également assigner A à (bc) et (de), et n'importe quel registre 8 bits à (hl).
- ld (bc),a → 02
- ld (de),a → 12
- ld (hl),b → 70
- ld (hl),c → 71
- ...
- ld (hl),l → 75
- ld (hl),a → 77
Notez qu'on ne peut pas assigner (hl) à (hl). L'instruction 76 s'appelle Halt, et il n'est même pas dit que je l'aborde dans ce tuto
C'était pas bien compliqué, avouons-le.
Assignation adresse vers registre
Ici c'est comme l'assignation registre vers adresse, sauf que c'est le contraire (je sais pas si je me fais bien comprendre ). C'est la même syntaxe sauf que les registres changent ENCORE de nom.
- ld a,(****) → 3A****
- ld bc,(****) → ED4B****
- ld de,(****) → ED5B****
- ld hl,(****) → 2A****
Donc, pour stocker le contenu de ... tiens ($8599) (cxpage sur 83 ) dans DE, on va faire
- Code:
ED5B9985
On peut aussi stocker (hl) dans n'importe quel registre 8 bits.
- ld b,(hl) → 46
- ld c,(hl) → 4E
- ld d,(hl) → 56
- ld e,(hl) → 5E
- ld h,(hl) → 66
- ld l,(hl) → 6E
- ld a,(hl) → 7E
En fait, si vous regardez le tableau des assignations registre vers registre, vous verrez que tout se suit mais qu'il y a un trou aux commandes *6 et *E : ce sont les assignations avec (hl), sauf 76 qui est HALT.
Assignation adresse vers adresse
Là encore c'est facile, on peut pas en fait retenez qu'une assignation contenant une adresse doit obligatoirement contenir un registre.
Exercice 2 : le retour
Grâce à ce qu'on sait, on va pouvoir améliorer un peu notre petit TP. On va maintenant choisir où HL devra s'afficher.
Concrètement, je vous demande de créer un programme qui affiche en tant que nombre (toujours avec DispHL = $4507 / $4709 ; utilisez comme adresse currow = $844B / $800C) l'abscisse de ce même nombre. En clair, ce nombre est positionné en (2;5), il doit donc afficher 2.
Je vous demande de jongler entre adresses et registres dans cet exercice.
- Correction:
- Ti-83
- Code:
:AsmPrgm
:110502
:ED534D84
:2600
:6A
:EF0745
:C9
- Code:
:110502
:ED530C80
:2600
:6A
:CD0947
:C9
:End
:0000
:End
110502 : stocke dans DE les coordonnées (2;5) (attention à bien inverser les octets)
ED534B84 / ED530C80: stocke DE dans l'adresse $844B / $800C, soit (currow)
2600 : stocke 00 dans H. Si on ne l'avait pas fait, comme on ne modifie que L mais qu'on affiche HL, les valeurs de H et de L se seraient superposées et on n'aurait pas affiché la bonne valeur.
6A : stocke D (contenant actuellement l'abscisse) dans L
EF0745 / CD0947 : appelle DispHL, qui va afficher HL, soit actuellement $0002 (car H = $00 et L = $02) = 2 en décimal (DispHL affiche en décimal).
Ce qu'il y a après le C9 ... cette fois on va l'utiliser !
Vous vous rappelez de ce qu'il y a généralement après le premier C9 (parce qu'on va voir qu'il peut y en avoir plusieurs) ? Des chaînes de caractères en général.
- Encodage d'une chaîne:
- A = $41
a = $61
Ajoutez $01 pour avoir la lettre suivante.
Par exemple e = a 4 = $61 $04 = $65
Donc, prenons un code hexa tout ce qu'il y a de plus classique, et ajoutons-lui la chaîne "Hello !" à la fin.
L'espace a pour code $20 et le point d'exclamation $21
- Code:
:AsmPrgm
:C9
:48656C6C6F202100
N'oubliez pas le 00 à la fin !
Vous pouvez tester ce code si ça vous chante, mais vous ne verrez rien .
Visuellement, ce programme ne fait rien. Concrètement, c'est beaucoup plus que ça.
Un petit tour chez les adresses
Quand on entre un programme hexa avec une chaîne comme celle-ci après le C9, cette chaîne est stockée dans une certaine adresse. Le truc chia embêtant, c'est que cette adresse varie selon la taille même de votre programme.
L'adresse de stockage initiale est $9D93 / $9327. Pour avoir l'adresse où est stockée notre texte, il faut ajouter à $9D93 / $9327 chaque octet du programme avant la chaîne de caractères (on ne compte pas la ou les autres chaînes, et sachant que AsmPrgm vaut 2 octets).
- Pour ceux qui font ou ont fait de l'ASM:
- Vous aurez sans doutes remarqué que cette valeur est celle que l'on spécifie à la commande .org dans le header d'un programme ASM :
- Code:
.org $9D93
Et sur 82 stats :
.org $9327
Euuuh je pense que je n'ai pas été très clair
Voici donc comment procéder :
Voici notre code :
- Code:
:AsmPrgm
:C9
:48656C6C6F202100
On part de $9D93 / $9327, et on ajoute $01 pour chaque groupe de deux caractères avant la chaîne (avec AsmPrgm = 2 octets). Ce qui nous fait $9D93 $03 = $9D96
Donc pour charger l'adresse du texte dans un registre (16 bits uniquement, c'est une adresse rappelons-le ; mais en général on utilise HL) il y a un groooos piège :On utilise le nom d'un registre comme si l'adresse du texte était une valeur normale.
En clair : si je vous avais dit "stockez la valeur de l'adresse $9D99 dans HL" (ben oui, $9D99 : il faut compter la commande de stockage elle-même ; elle vaut trois octets), sachant ce que vous savez sur les adresses vous m'auriez mis :
- Code:
2A999D
- Code:
21999D
Sur 82 stats, c'est pareil, sauf que comme je l'ai dit on commence à $9327 et qu'il n'y a pas de AsmPrgm.
Bon, toujours est-il que maintenant que vous connaissez la marche à suivre, on va enfin pouvoir faire notre Hello world !
Le tant espéré Hello world
Comme ici c'est un peu plus compliqué que d'habitude, on va le faire ensemble ce Hello world.
Prenons donc un code de base :
- Code:
:AsmPrgm
:C9
- Code:
:C9
:End
:0000
:End
- Code:
:AsmPrgm
:C9
:48656C6C6F20776F726C64202100
- Code:
:C9
:48656C6C6F20776F726C64202100
:End
:0000
:End
Nous avons donc notre chaîne de caractères. Déjà pour faire beau on va effacer l'écran avec ClrLCDFull ($4540 / $4755), puis comme on veut afficher notre chaîne au milieu de l'écran et en minuscules (si si, on veut , avec vPuts et tout) on va stocker les coordonnées ($1A;$1A) (soit 26;26) dans DE et stocker DE dans penCol (situé à l'adresse $86D7 / $8252) :
- Code:
:AsmPrgm
:EF4045
:111A1A
:ED53D786
:C9
:48656C6C6F20776F726C64202100
- Code:
:CD5547
:111A1A
:ED535282
:C9
:48656C6C6F20776F726C64202100
:End
:0000
:End
Maintenant, on appelle vPuts ($4561 / $4781) pour écrire le texte à l'adresse pointée par HL en petits caractères :
- Code:
:AsmPrgm
:EF4045
:111A1A
:ED53D786
:
:EF6145
:C9
:48656C6C6F20776F726C64202100
- Code:
:CD5547
:111A1A
:ED535282
:
:CD8147
:C9
:48656C6C6F20776F726C64202100
:End
:0000
:End
Maintenant, vous savez comment assigner cette chaîne. Alors faites-le sachant que si vous vous trompez, tant que vous mettez bien 21 au début ça ne fera qu'afficher une valeur fausse.
Rappelez-vous que la valeur de départ est $9D93 / $9327, et qu'il faut ajouter $01 à chaque octet du programme avant le C9, en incluant le C9 lui-même ainsi que la commande d'assignation à HL (mesurant 3 octets).
- Solution:
- Code:
Ti-83 :
:21A89D
Ti-82 stats :
:213893
On a donc notre code final :
- Code:
:AsmPrgm
:EF4045
:111A1A
:ED53D786
:21A89D
:EF6145
:C9
:48656C6C6F20776F726C64202100
- Code:
:CD5547
:111A1A
:ED535282
:213893
:CD8147
:C9
:48656C6C6F20776F726C64202100
:End
:0000
:End
Entrez ce code sur votre calculatrice (je l'ai testé personnellement sur calculatrice, il marche), si vous avez peur de vous tromper entrez-le sur émulateur, mais testez-le !
Et vous obtenez :
[Vous devez être inscrit et connecté pour voir cette image]
Magnifique non ?
Les tests, les sauts, les sauts conditonnels et les getkey's
Les tests
Tous les programmeurs connaissent cette instruction, celle qui est apprise dès les débuts, je parle bien sûr de l'instruction IF. Eeeet malheureusement, cette commande n'existe pas en hexa, et pas plus qu'en ASM d'ailleurs. Mais alors me direz-vous, comment tester la valeur de ceci ou cela ?
Pour répondre à cette question, un petit cours d'ASM s'impose.
En ASM, pour effectuer un test, la solution la plus répandue s'appelle CP. Non, rien à voir avec les Classes Préparatoires, mais bien avec les tests.
Cette fonction est un peu spéciale car elle simule une soustraction sur A, car je vous rappelle qu'on ne peut effectuer des opérations que sur l'Accumulateur.
Comment ça elle simule, et bien en fait cette instruction ne modifie pas la valeur de A, d'une part, et modifie quand même les flags liés à A, d'autre part. Je m'explique.
Les flags sont des bits (donc soit 0 soit 1) décrivant chacun une action ou un état. Les flags les plus utilisés sont ceux décrivant A :
- Le flag Z (Zero) est activé (mis à 1) si A = 0. Sinon il est désactivé (mis à 0).
- Le flag S (Sign) contient le signe de A. Retenez-le si vous voulez, toujours est-il qu'il est activé si A est négatif et désactivé si A est positif (oui je sais moi aussi j'aurai dit l'inverse )
- Le flag P (Parity) est activé si A contient un nombre impair et désactivé s'il contient un nombre pair.
- Le flag V (dépassement ?) est activé si A est inférieur à -127 ou supérieur à 127, Sinon il est désactivé.
- Le flag C (Carry, un des plus utilisés) est activé si A est inférieur à 0 ou supérieur à 255 (qui je le rappelle, est la valeur maximale d'un registre 8 bits = 11111111), sinon il est désactivé. Il ressemble à V mais travaille en non-signé (uniquement positif).
- Il existe deux autres flags, H et N, mais nous n'en parlerons pas car ils ne s'utilisent que dans un seul cas bien spécifique.
Si vous ne deviez retenir que deux de ces flags, retenez C et Z, ce sont à ma connaissance les plus utiles en le plus de circonstances.
Revenons à notre instruction CP. Je disais tout à l'heure qu'elle simulait une soustraction (on parle de soustraction virtuelle). En réalité cette commande ne modifie en aucun cas la valeur d'aucun registre, mais met à jour tous les flags de A. Ainsi, prenons ce code :
- Code:
ld a,$04
cp $05
Après la première instruction, on a A = $04. Donc si on fait un résumé des flags :
- Z = 0
- S = 0
- P = 0
- V = 0
- C = 0
- Z = 0 car $04 - $05 ≠ 0
- S = 1 car $04 - $05 < 0
- P = 1 car $04 - $05 est impair
- V = 0 car $04 - $05 > -127 et < 127
- C = 1 car $04 - $05 < 0
Au vu de ces flags, on peut déduire que si Z est activé, tous les autres sont désactivés et si S est activé, C l'est aussi.
C'est fini pour la partie ASM, voyons maintenant l'hexa.
En hexa, CP se traduit par FE, et cette commande FE est la réplique exacte de CP :
- Code:
CP $4B
Se traduit par
FE4B
ATTENTION ! Ne confondez jamais FE, qui exerce une soustraction virtuelle avec EF, qui appelle une romcall !
Les flags de A sont les mêmes en hexa qu'en ASM, c'est juste que comme tout registre ou adresse en hexa, ils ne s'appellent pas pareil et change de nom selon le contexte
Les sauts
Sortons un peu du contexte de la condition en voyant les sauts. Bien sûr, c'est uniquement pour y replonger ensuite avec plus de ressources
Le principe du saut en programmation est qu'à un certain endroit d'un programme, on a une instruction qui dit "va directement à l'instruction située à l'adresse xxx sans exécuter ce qui la sépare de moi". C'est exactement le principe de Lbl et Goto en basic (et comme dans un bon paquet de langages d'ailleurs).
En ASM comme en hexa, il y a plusieurs fonctions de sauts (je parle des non conditionnels, on verra les conditionnels juste après). Les plus répandues sont JR et JP.
La différence entre ces deux instructions, hormis le fait que JR prend deux octet et JP trois, est la portée de leur saut : alors que JR peut sauter 128 = $80 octets en avant ou en arrière dans le programme, JP peut sauter 32 kilo octets = 32768 octets = $8000 en avant ou en arrière, c'est à dire toute la RAM en fait
On dit que JR exerce un saut relatif et JP un saut absolu, vous allez comprendre pourquoi.
La syntaxe de ces deux commandes est en ASM :
- Code:
jp/jr [adresse]
MAIS heureusement, pour la commande JR en hexa, commande qui s'appelle 18, retenez-le, on ne doit pas renseigner l'adresse exacte ! On doit juste renseigner de combien d'octets avancer ou reculer. C'est l'adresse relative, car elle dépend du point de départ.
Mais comment on sait si on avance ou on recule ?
Vous vous rappelez que JR saute de 128 octets en avant ou en arrière ? Et quelle est la valeur maximale qu'on peut représenter avec 8 bits ?
- Spoiler:
- $FF, soit 255 = 128 x 2 (- 1 en comptant le 0) !
En fait, le sens du saut va dépendre de la valeur que vous passez en argument. Si la valeur est entre $01 et $7F, le saut va d'autant d'octets vers l'avant. Si la valeur passée en argument va de $80 à $FF, le programme recule de $100 - [valeur] octets. Exemple :
- Code:
18F8
Comme pour charger du texte, pour connaître l'éloignement en octets de votre instruction où sauter, la meilleure méthode reste encore de compter les groupes de deux caractères. Re-exemple :
- Code:
1808 Un deux octets
EF4045 Trois quatre cinq octets
210101 Six Sept Huit octets
EF7249 cette ligne sera exécutée, contrairement aux 2 précédentes
Notez que l'instruction 18xx est comptée dans le nombre d'octets à sauter. Vous aurez donc compris que
- Code:
1802
Faites très attention à ne pas débouler au milieu d'une instruction, ça dérèglerait complètement le programme, d'où l'intérêt de structurer son code avec une seule instruction par ligne pour mieux se repérer.
Pour l'instruction JP, en ASM sa syntaxe ne change pas mais en hexa, cette fois il faut renseigner l'adresse exacte (donc 16 bits, théoriquement de $0000 à $FFFF mais notre programme commence à $9D93 / $9327) du point de reprise. On parle d'adresse absolue car on veut l'adresse exacte en dur de l'endroit où sauter. C'est d'ailleurs très dangereux si vous ne savez pas par coeur où votre programme commence (pis de toute façon en hexa c'est rare d'avoir à sauter plus de 128 octets ).
La commande JP s'écrit donc en hexadécimal C3 et prend en arguments une valeur 16 bits qui ne peut pas être un registre, ça doit être une adresse en dur, toujours en sachant que votre programme débute en $9D93 / $9327 (ce qui fait 3 octets, un de plus que JR).
- Code:
AsmPrgm <--- commencez à compter ici : cette ligne est à l'adresse $9D93
EF4045
3E4B
218724
C3959D <-- cette ligne retourne au début, donc ce programme est une boucle infinie
Les sauts conditionnels
Retour aux conditions donc, et cette fois nous allons réellement pouvoir traduire l'instruction If en hexa (et non pas de Else ici ) !
Pour réaliser un saut conditionnel, le principe est de tester la valeur d'un flag puis de réaliser un saut (absolu ou relatif) si le flag testé est activé. Dans notre cas de traduction de If, on utilisera un saut conditionnel juste après une commande CP (ou FE en hexa, souvenez-vous). Nous allons donc tester les flags de A.
Attends ça veut dire qu'on ne peut pas tester si le bit est désactivé ?
Oui et non. En réalité, chaque flag de A est "dédoublé" pendant un test en une version "inversée". Ainsi, les flags classiques de A dérivent en :
- Z (Zero)
- NZ (Non Zero)
- C (Carry)
- NC (No Carry)
- PO (Parity Odd, activé si A impair)
- PE (Parity Even, activé si A pair)
- P (Positive)
- M (Minus, activé si A négatif)
Les instructions de sauts conditionnels les plus répandues sont ... JR et JP. Ah tiens, comme on se retrouve
En fait, en ASM il peut y avoir deux notations à ces commandes :
- Code:
jr/jp [adresse] ; le saut se fera obligatoirement
jr/jp [flag],[adresse] ; le saut se fera si le flag est activé
Par contre, ATTENTION, EXCEPTION : avec JR, on ne peut pas tester l'état de PO, PE, P ni M. En ASM ça fera une erreur de compilation et en hexa la commande n'existe carrément pas
Justement, à propos de ça : à chaque flag à tester avec JR ou JP correspond une commande. Par exemple, le saut relatif obligatoire de $2D octets en avant se notera :
- Code:
182D
- Code:
282D
Le saut s'effectuera uniquement si A = 0
Voici donc une liste des dérivées de JR :
- 18[adresse relative] : saute obligatoirement
- 20[adresse relative] : saute si NZ est activé (si A ≠ 0)
- 28[adresse relative] : saute si Z est activé (si A = 0)
- 30[adresse relative] : saute si NC est activé (si A appartient à [0;255])
- 38[adresse relative] : saute si C est activé (si A < 0 ou A > 255)
Vous remarquerez qu'il y a une commande tous les 8 bits, car par exemple $30 (test de NC) - $28 (test de Z) = $08. Ça prouve bien qu'il y a une part de logique dans ce que je vous apprends .
Et voici celles de JP :
- C3[adresse absolue] : saute obligatoirement
- C2[adresse absolue] : saute si NZ est activé
- CA[adresse absolue] : saute si Z est activé
- D2[adresse absolue] : saute si NC est activé
- DA[adresse absolue] : saute si C est activé
- E2[adresse absolue] : saute si PO est activé (Parity Odd, si A contient un nombre impair)
- EA[adresse absolue] : saute si PE est activé (Parity Even, si A contient un nombre pair)
- F2[adresse absolue] : saute si P est activé (si A est positif)
- FA[adresse absolue] : saute si M est activé (Minus, si A est négatif)
Vous remarquerez que l'adresse du saut obligatoire suis également l'ordre des sauts conditionnels. Vous remarquerez également que JP peut tester deux fois plus de flags que JR. Il est effectivement la seule solution pour tester la parité (pair / impair), et une solution plus sûre pour tester le signe (vous pouvez très bien tester le signe avec C (Carry), qui s'active si A est plus petit que 0, mais faites attention car il s'active aussi s'il est plus grand que 255).
Grâce à ça, on peut traduire le code :
- Code:
If A≠6
Then
ClrHome
Else
getkey
End
- Code:
:AsmPrgm
:FE06
:2805
:EF4045
:1803
:EF7249
:C9
- Code:
:FE06
:2805
:CD5547
:1803
:CDFE4C
:C9
:End
:0000
:End
Explicons ce code :
- FE06 soustrait virtuellement $06 à A et met les flags à jour.
- 2805 teste le flag Z ; s'il est activé c'est que A - 6 = 0 (et donc que A = 6), alors on saute les 5 prochains octets (correspondant à "ClrHome Else"). Si le flag Z est désactivé, c'est que A - 6 est différent de 0, donc que A est différent de 6, alors on continue normalement.
- EF4045 / CD5547: appelle la romcall ClrLCDFull ($4540 / $4755), plus ou moins l'équivalent de ClrHome (depuis le temps, vous devriez savoir comment appeler une romcall ).
- 1803 : si cette ligne de code est lue, c'est que A est différent de 6, donc on saute les trois prochains octets car ils sont l'action à exécuter si A était égal à 6. Cette ligne est l'équivalent du Else et "saute jusqu'au End".
- EF7249 / CDFE4C: si cette ligne de code est lue, c'est que A = 6, et correspond à getkey, se situant après le Else (elle appelle d'ailleurs la romcall _getkey $4972 / $4CFE).
Dis comme ça, ça a peut-être l'air super dur, mais en fait c'est tout bête : on soustrait virtuellement, on teste un flag, on saute au bon endroit et on re-saute pour éviter le code qui aurait été exécuté le cas échéant.
Un cas d'application concret : le getkey
Vous devez être un peu sceptiques quand aux possibilités d'application de cette méthode. Et bien je vais vous en apprendre une bien bonne : la romcall getkey ($4972 / $4CFE) attend une touche et stocke sa valeur dans A. Et rappelez-moi, c'est sur quel registre qu'agit CP déjà ? Sur A !
On peut donc soustraire virtuellement à A la valeur d'une touche (que vous pourrez trouver dans ultimate.inc et ti83asm.inc, leur nom commence tous par k), on teste Z pour voir si A correspond et on agit en conséquence !
En général, le nom des touches dans les includes est un k suivi de ce qui est écrit sur la touche (en Anglais !). Par exemple la touche Y= (ou f(x) pour les Ti plus récentes) s'appelle kyequ. Autre exemple : la flèche du haut s'appelle kup. Notez qu'il existe kmem (le menu accessible par [2nd] [ ]) et une touche pour tous les menus accessibles par [2nd]. Notez aussi qu'il est impossible de détecter [2nd] ni [alpha] (pour le moment ).
Les getkey's : application
Non non on ne va pas coder une app , mais VOUS allez plutôt écrire un programme à l'aide de ce que j'espère vous avoir appris dans ce chapitre.
Vous allez donc écrire un programme complet (avec le bon format et tout), qu'on peut exécuter sur calto sans danger (toujours préciser ) et qui attend une touche : si la touche 5 est appuyée, le programme attend une nouvelle touche, et si cette touche est la flèche droite, il quitte. Si à une quelconque étape du programme la mauvaise touche est pressée, il repart au début.
- Indice 1:
- Si vous avez la flemme de chercher dans les includes, la touche 5 s'appelle k5 et sa valeur est $93, et la flèche de droite s'appelle kright et sa valeur est $01.
- Indice 2:
- Maintenant je sais que vous regardez les indices avant de réfléchir
- Correction:
- Vous allez voir, le programme est encore plus court que le Hello world qu'on a fait :
- Code:
AsmPrgm
EF7249
FE93
2802
18F9
EF7249
FE01
2802
18F7
C9
- Code:
CDFE4C
FE93
2802
18F9
CDFE4C
FE01
2802
18F7
C9
End
0000
End
Ces structures imbriquées devraient vous rappeler le Ti-Basic
Voilà, vous avez parfaitement le niveau pour faire des "vrais" programmes sympas, qui réagissent aux touches et tout ! Rappelez-vous qu'il y a plein de romcalls, dont des romcalls graphiques, qui utilisent seulement les registres comme arguments, et sont de ce fait facile à utiliser en hexa : on assigne valeur à registre, un petit coup de EF ou CD et hop ! On a un beau truc
Les boucles
En Ti-Basic (et dans tous les autres langages de programmation à part l'ASM) existe le concept de boucles. Ces boucles peuvent s'appeler For(), While(), Repeat() ou même DS<() ou n'importe quoi d'autre, leur utilité sera toujours de répéter des actions tant qu'une condition est vraie (ou fausse).
En ASM et en hexa, l'instruction qui se rapproche le plus d'une boucle a un nom barbare et ressemble de très près aux boucles For() et DS<(), j'ai nommé DJNZ. Aaaah ben oui je vous avais prévenu, c'est un nom barbare ! Vous comprendrez peut-être son utilité si je vous dit ce qu'elle signifie : Decrement and Jump if Non-Zero. Si vous voyez toujours pas, vu que cette phrase ne veut rien dire en Français, je vous donne carrément son mode de fonctionnement.
Cette instruction s'écrit en ASM de la manière suivante :
- Code:
djnz [adresse]
- Registre:
Donc, DJNZ va décrémenter B (lui soustraire 1, pas virtuellement cette fois) et sauter à l'adresse spécifiée si B est différent de 0. On comprend tout de suite mieux la signification du nom là hein ?
Cette instruction DJNZ est l'équivalent ASM de :
- Code:
For([variable quelconque],B,0,-1)
Donc en gros, pour faire un truc 5 fois en ASM, on écrira :
- Code:
ld b,$05
start: ; un label pour pouvoir reprendre
... ; le code à exécuter 5 fois ici
djnz start : décrémente B et retourne au label start si B ≠ 0
ret ; si B = 0, quitte le programme
Donc, en hexa DJNZ s'appelle 10. Sympa, facile à retenir et tout . La voici donc utilisée :
- Code:
AsmPrgm
EF4045
0605 ← on stocke 5 dans B pour faire une boucle qui tournera 5 fois
EF7249
10FD ← si B ≠ 0, on retourne 3 octets en arrière
C9
- Code:
CD5547
0605 ← on stocke 5 dans B pour faire une boucle qui tournera 5 fois
CDFE4C
10FD ← si B ≠ 0, on retourne 3 octets en arrière
C9
End
0000
End
ATTENTION ! Veillez bien à ne pas modifier la valeur de B pendant l'utilisation de DJNZ, car cela aboutirai à une boucle infinie, B étant modifiée à chaque tour de boucle et remise à sa valeur initiale !
Tout le tuto ne tient pas dans un seul message, donc voyez la suite ici : [Vous devez être inscrit et connecté pour voir ce lien]
Dernière édition par matrefeytontias le Sam 4 Mai - 9:59, édité 24 fois
matrefeytontias- Platinum 1
- Sexe :
Age : 27
Messages : 1383
Date d'inscription : 28/09/2011
Etudes : 1ère S SI
Points Forum : 90
Points Concours : 7
Langages :- - ASM TI-82 Stats / TI-83
- - ASM TI-83+ / TI-84+
- - Axe Parser
- - Lua Nspire
- - Ndless Nspire
- - TI-83+.fr
- - TI-Nspire CAS
Re: Programmer en hexadécimal ... c'est possible !!!
Ouin, RAM cleared ! :'(
Imputée, imputée... c'moi qui vais t'amputer, ouais...
J'rigoleuh.
Bon article. Je te mets un plus.
Surtout vu le temps que tu a passé a le travailler, vu l'heure ou tu l'as posté !
Imputée, imputée... c'moi qui vais t'amputer, ouais...
J'rigoleuh.
Bon article. Je te mets un plus.
Surtout vu le temps que tu a passé a le travailler, vu l'heure ou tu l'as posté !
persalteas- Platinum 2
- Sexe :
Age : 29
Messages : 2068
Date d'inscription : 30/06/2010
Etudes : PACES (médecine)
Points Forum : 114
Points Concours : 10
Langages :- - TI-Basic Z80
- - xLib
- - Grammer
- - TI-Basic Nspire
- - TI-82 Stats.fr
- - TI-83
- - TI-83+
- - TI-84+ SE
- - TI-86
- - TI-Nspire
- - TI-Nspire CX
- - Casio Collège
- - Casio Graph
Re: Programmer en hexadécimal ... c'est possible !!!
Merci !
J'ai mis 3h à écrire le tuto tout en cherchant le code, ça a fait long !
J'ai mis 3h à écrire le tuto tout en cherchant le code, ça a fait long !
matrefeytontias- Platinum 1
- Sexe :
Age : 27
Messages : 1383
Date d'inscription : 28/09/2011
Etudes : 1ère S SI
Points Forum : 90
Points Concours : 7
Langages :- - ASM TI-82 Stats / TI-83
- - ASM TI-83+ / TI-84+
- - Axe Parser
- - Lua Nspire
- - Ndless Nspire
- - TI-83+.fr
- - TI-Nspire CAS
Re: Programmer en hexadécimal ... c'est possible !!!
Hahahah toi aussi tu crées des topics à 4 heures et quelques du matin... enfin bref ton article merci pour tes efforts tardifs.
noelthebest- Platinum 1
- Sexe :
Age : 27
Messages : 1971
Date d'inscription : 12/03/2011
Etudes : ENS Cachan
Points Forum : 20
Points Concours : 9
Langages :- - TI-Basic Z80
- - ASM TI-83+ / TI-84+
- - Axe Parser
- - TI-83+.fr
- - TI-Nspire CX
- - Casio Collège
- - Casio Graph
Re: Programmer en hexadécimal ... c'est possible !!!
noelthebest a écrit:Hahahah toi aussi tu crées des topics à 4 heures et quelques du matin... enfin bref ton article merci pour tes efforts tardifs.
"Enfin bref ton article" ?
matrefeytontias- Platinum 1
- Sexe :
Age : 27
Messages : 1383
Date d'inscription : 28/09/2011
Etudes : 1ère S SI
Points Forum : 90
Points Concours : 7
Langages :- - ASM TI-82 Stats / TI-83
- - ASM TI-83+ / TI-84+
- - Axe Parser
- - Lua Nspire
- - Ndless Nspire
- - TI-83+.fr
- - TI-Nspire CAS
Re: Programmer en hexadécimal ... c'est possible !!!
Update dans la partie "Structurer son code hexadécimal" sur la séparation d'instruction, désolé pour le double-post
matrefeytontias- Platinum 1
- Sexe :
Age : 27
Messages : 1383
Date d'inscription : 28/09/2011
Etudes : 1ère S SI
Points Forum : 90
Points Concours : 7
Langages :- - ASM TI-82 Stats / TI-83
- - ASM TI-83+ / TI-84+
- - Axe Parser
- - Lua Nspire
- - Ndless Nspire
- - TI-83+.fr
- - TI-Nspire CAS
Re: Programmer en hexadécimal ... c'est possible !!!
ça à l'air pas mal, mais il faut quand même le faire pour programmer en héxa (enfin, avant d'avoir le cable, je cherchais bien comment lle faire sur TI82stats.fr).
Sandro
PS : allez, un +1 de ma part aussi
Sandro
PS : allez, un +1 de ma part aussi
sandro- Or 4
- Sexe :
Age : 28
Messages : 806
Date d'inscription : 01/07/2011
Etudes : T°S SVT spé maths
Points Forum : 29
Points Concours : 5
Langages :- - TI-Basic Z80
- - ASM TI-82 Stats / TI-83
- - ASM TI-83+ / TI-84+
- - Axe Parser
- - TI-82 Stats.fr
- - TI-84+ SE
- - TI-89
- - Casio Collège
Re: Programmer en hexadécimal ... c'est possible !!!
Gros update sur les registres, j'ai découvert toutes les adresses des registres dans un cas d'assignation hexa vers registre. Et j'ai aussi vu que F et AF n'existent pas en hexa ! . J'ai également mis un mini-TP à la fin.
matrefeytontias- Platinum 1
- Sexe :
Age : 27
Messages : 1383
Date d'inscription : 28/09/2011
Etudes : 1ère S SI
Points Forum : 90
Points Concours : 7
Langages :- - ASM TI-82 Stats / TI-83
- - ASM TI-83+ / TI-84+
- - Axe Parser
- - Lua Nspire
- - Ndless Nspire
- - TI-83+.fr
- - TI-Nspire CAS
Re: Programmer en hexadécimal ... c'est possible !!!
Et si tu mettais ça sur le site du zér0 aussi ? :D
noelthebest- Platinum 1
- Sexe :
Age : 27
Messages : 1971
Date d'inscription : 12/03/2011
Etudes : ENS Cachan
Points Forum : 20
Points Concours : 9
Langages :- - TI-Basic Z80
- - ASM TI-83+ / TI-84+
- - Axe Parser
- - TI-83+.fr
- - TI-Nspire CX
- - Casio Collège
- - Casio Graph
Re: Programmer en hexadécimal ... c'est possible !!!
T'es fou, ça passerait jamais ! Je connais pas assez l'ASM et encore moins l'hexa pour faire un truc complet au point qu'il soit accepté.
matrefeytontias- Platinum 1
- Sexe :
Age : 27
Messages : 1383
Date d'inscription : 28/09/2011
Etudes : 1ère S SI
Points Forum : 90
Points Concours : 7
Langages :- - ASM TI-82 Stats / TI-83
- - ASM TI-83+ / TI-84+
- - Axe Parser
- - Lua Nspire
- - Ndless Nspire
- - TI-83+.fr
- - TI-Nspire CAS
Re: Programmer en hexadécimal ... c'est possible !!!
Pas bête... au pire mets-le en bêta-test, ou mieux encore demande à mdr1 d'intégrer ça, à son tutoriel.
noelthebest- Platinum 1
- Sexe :
Age : 27
Messages : 1971
Date d'inscription : 12/03/2011
Etudes : ENS Cachan
Points Forum : 20
Points Concours : 9
Langages :- - TI-Basic Z80
- - ASM TI-83+ / TI-84+
- - Axe Parser
- - TI-83+.fr
- - TI-Nspire CX
- - Casio Collège
- - Casio Graph
Re: Programmer en hexadécimal ... c'est possible !!!
Oui enfin j'en connais quand même assez pour que ça soit conséquent, pas juste un chapitre.
L'hexa, c'est juste une traduction hexadécimale de commandes ASM, rien de plus (sauf quelques trucs quoi, exemple très chiant l'assignation )
L'hexa, c'est juste une traduction hexadécimale de commandes ASM, rien de plus (sauf quelques trucs quoi, exemple très chiant l'assignation )
matrefeytontias- Platinum 1
- Sexe :
Age : 27
Messages : 1383
Date d'inscription : 28/09/2011
Etudes : 1ère S SI
Points Forum : 90
Points Concours : 7
Langages :- - ASM TI-82 Stats / TI-83
- - ASM TI-83+ / TI-84+
- - Axe Parser
- - Lua Nspire
- - Ndless Nspire
- - TI-83+.fr
- - TI-Nspire CAS
Re: Programmer en hexadécimal ... c'est possible !!!
désolé je suis obligé de double-poster à chaque update
J'ai donc entièrement terminé le chapitre sur les registres et l'assignation. Je me rends compte de plus en plus que c'est le tutoriel de l'extrême ce truc Enjoy !
J'ai donc entièrement terminé le chapitre sur les registres et l'assignation. Je me rends compte de plus en plus que c'est le tutoriel de l'extrême ce truc Enjoy !
matrefeytontias- Platinum 1
- Sexe :
Age : 27
Messages : 1383
Date d'inscription : 28/09/2011
Etudes : 1ère S SI
Points Forum : 90
Points Concours : 7
Langages :- - ASM TI-82 Stats / TI-83
- - ASM TI-83+ / TI-84+
- - Axe Parser
- - Lua Nspire
- - Ndless Nspire
- - TI-83+.fr
- - TI-Nspire CAS
Re: Programmer en hexadécimal ... c'est possible !!!
sinon, propose le en mini-tuto
sandro- Or 4
- Sexe :
Age : 28
Messages : 806
Date d'inscription : 01/07/2011
Etudes : T°S SVT spé maths
Points Forum : 29
Points Concours : 5
Langages :- - TI-Basic Z80
- - ASM TI-82 Stats / TI-83
- - ASM TI-83+ / TI-84+
- - Axe Parser
- - TI-82 Stats.fr
- - TI-84+ SE
- - TI-89
- - Casio Collège
Re: Programmer en hexadécimal ... c'est possible !!!
C'est trop conséquent pour un mini tuto ...
matrefeytontias- Platinum 1
- Sexe :
Age : 27
Messages : 1383
Date d'inscription : 28/09/2011
Etudes : 1ère S SI
Points Forum : 90
Points Concours : 7
Langages :- - ASM TI-82 Stats / TI-83
- - ASM TI-83+ / TI-84+
- - Axe Parser
- - Lua Nspire
- - Ndless Nspire
- - TI-83+.fr
- - TI-Nspire CAS
Re: Programmer en hexadécimal ... c'est possible !!!
tu poura toujours le faire passer en gros quand tu aura eut le temps de le structurer tranquillement et que tu esimera qu'il est suffisament "complet"
sandro- Or 4
- Sexe :
Age : 28
Messages : 806
Date d'inscription : 01/07/2011
Etudes : T°S SVT spé maths
Points Forum : 29
Points Concours : 5
Langages :- - TI-Basic Z80
- - ASM TI-82 Stats / TI-83
- - ASM TI-83+ / TI-84+
- - Axe Parser
- - TI-82 Stats.fr
- - TI-84+ SE
- - TI-89
- - Casio Collège
Re: Programmer en hexadécimal ... c'est possible !!!
J'ai déjà essayé la même technique avec un autre tuto, c'est carrément pas passé ...
matrefeytontias- Platinum 1
- Sexe :
Age : 27
Messages : 1383
Date d'inscription : 28/09/2011
Etudes : 1ère S SI
Points Forum : 90
Points Concours : 7
Langages :- - ASM TI-82 Stats / TI-83
- - ASM TI-83+ / TI-84+
- - Axe Parser
- - Lua Nspire
- - Ndless Nspire
- - TI-83+.fr
- - TI-Nspire CAS
Re: Programmer en hexadécimal ... c'est possible !!!
T'as réussi à faire des trucs ?
Sinon, tu pourrais rajouter une option "hexadécimal" dans la section "langages" du profil ? Voire même plusieurs parce que l'hexa change entre Ti-76, 82stats/83, 83+/84+ ... Ça serait marrant Et puis tiens pourquoi pas un groupe "Programmeurs de l'extrême" qui regrouperait tous ceux qui programment en hexa ?
matrefeytontias- Platinum 1
- Sexe :
Age : 27
Messages : 1383
Date d'inscription : 28/09/2011
Etudes : 1ère S SI
Points Forum : 90
Points Concours : 7
Langages :- - ASM TI-82 Stats / TI-83
- - ASM TI-83+ / TI-84+
- - Axe Parser
- - Lua Nspire
- - Ndless Nspire
- - TI-83+.fr
- - TI-Nspire CAS
Re: Programmer en hexadécimal ... c'est possible !!!
Humour, humour
Sinon, juste pour savoir est-ce quelqu'un a essayé de faire quelque chose ou est-ce que mon tuto fais juste beau pour l'instant ?
Sinon, juste pour savoir est-ce quelqu'un a essayé de faire quelque chose ou est-ce que mon tuto fais juste beau pour l'instant ?
matrefeytontias- Platinum 1
- Sexe :
Age : 27
Messages : 1383
Date d'inscription : 28/09/2011
Etudes : 1ère S SI
Points Forum : 90
Points Concours : 7
Langages :- - ASM TI-82 Stats / TI-83
- - ASM TI-83+ / TI-84+
- - Axe Parser
- - Lua Nspire
- - Ndless Nspire
- - TI-83+.fr
- - TI-Nspire CAS
Re: Programmer en hexadécimal ... c'est possible !!!
Pour l'instant je suis plutôt en train de me remettre à l'asm pour pouvoir tester ton IDE (ce que je ferais dès que tu m'aura révelé comment et où on définit les variables (avec #define) pour ce header abrégé).
D'abbord le compilé, ensuite je pourrais peut-être songer à essayer de le refaire à la main.
Sandro
D'abbord le compilé, ensuite je pourrais peut-être songer à essayer de le refaire à la main.
Sandro
sandro- Or 4
- Sexe :
Age : 28
Messages : 806
Date d'inscription : 01/07/2011
Etudes : T°S SVT spé maths
Points Forum : 29
Points Concours : 5
Langages :- - TI-Basic Z80
- - ASM TI-82 Stats / TI-83
- - ASM TI-83+ / TI-84+
- - Axe Parser
- - TI-82 Stats.fr
- - TI-84+ SE
- - TI-89
- - Casio Collège
Re: Programmer en hexadécimal ... c'est possible !!!
ben avec les #define faut surtout pas le faire
il faut la définir avec
il faut la définir avec
- Code:
variable = saferam1
- Code:
ld registre,valeur
ld (variable),registre
Dernière édition par matrefeytontias le Lun 12 Déc - 21:01, édité 1 fois
matrefeytontias- Platinum 1
- Sexe :
Age : 27
Messages : 1383
Date d'inscription : 28/09/2011
Etudes : 1ère S SI
Points Forum : 90
Points Concours : 7
Langages :- - ASM TI-82 Stats / TI-83
- - ASM TI-83+ / TI-84+
- - Axe Parser
- - Lua Nspire
- - Ndless Nspire
- - TI-83+.fr
- - TI-Nspire CAS
Re: Programmer en hexadécimal ... c'est possible !!!
matrefeytontias a écrit:
T'as réussi à faire des trucs ?
Sinon, tu pourrais rajouter une option "hexadécimal" dans la section "langages" du profil ? Voire même plusieurs parce que l'hexa change entre Ti-76, 82stats/83, 83+/84+ ... Ça serait marrant Et puis tiens pourquoi pas un groupe "Programmeurs de l'extrême" qui regrouperait tous ceux qui programment en hexa ?
T'as d'autres idées comme ça tant qu'on y est ? Pour les âneries sans fin je t'aurais mis 9/10 tu vois.
Enfin bref, bonne continuation, si tu trouves d'autres trucs... ça serait bien que quelqu'un puisse fait un tutoriel COMPLET sur l'asm sur le site du zér0 (mdr1 a abandonné le sien on dirait) , si tu es volontaire... moi je suis partant.
noelthebest- Platinum 1
- Sexe :
Age : 27
Messages : 1971
Date d'inscription : 12/03/2011
Etudes : ENS Cachan
Points Forum : 20
Points Concours : 9
Langages :- - TI-Basic Z80
- - ASM TI-83+ / TI-84+
- - Axe Parser
- - TI-83+.fr
- - TI-Nspire CX
- - Casio Collège
- - Casio Graph
Re: Programmer en hexadécimal ... c'est possible !!!
Je suis au courant merci, c'était pas sérieux
En plus je connais pas trop trop l'ASM, pour l'instant je fais que compiler des petits programmes ne servant à rien pour avoir leur équivalent hexa
En plus je connais pas trop trop l'ASM, pour l'instant je fais que compiler des petits programmes ne servant à rien pour avoir leur équivalent hexa
matrefeytontias- Platinum 1
- Sexe :
Age : 27
Messages : 1383
Date d'inscription : 28/09/2011
Etudes : 1ère S SI
Points Forum : 90
Points Concours : 7
Langages :- - ASM TI-82 Stats / TI-83
- - ASM TI-83+ / TI-84+
- - Axe Parser
- - Lua Nspire
- - Ndless Nspire
- - TI-83+.fr
- - TI-Nspire CAS
Page 1 sur 6 • 1, 2, 3, 4, 5, 6
Sujets similaires
» Programmer en hexadécimal ?
» [FAQ hexadécimal] Posez ici vos questions sur l'hexadécimal 82 stats/83/83+/84+
» [83+/84+]Programmer en Grammer: la pratique
» hexadecimal...
» format en héxadécimal des nombres réels
» [FAQ hexadécimal] Posez ici vos questions sur l'hexadécimal 82 stats/83/83+/84+
» [83+/84+]Programmer en Grammer: la pratique
» hexadecimal...
» format en héxadécimal des nombres réels
Page 1 sur 6
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum