{"id":796,"date":"2019-06-15T18:51:14","date_gmt":"2019-06-15T16:51:14","guid":{"rendered":"https:\/\/ceobeta.oric.org\/?p=796"},"modified":"2019-06-15T18:51:14","modified_gmt":"2019-06-15T16:51:14","slug":"fonctionnement-de-la-pile-materiel-du-6502-4-8","status":"publish","type":"post","link":"https:\/\/oric.bqtt.net\/index.php\/2019\/06\/15\/fonctionnement-de-la-pile-materiel-du-6502-4-8\/","title":{"rendered":"Fonctionnement de la pile mat\u00e9rielle du 6502 (4\/8)"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><strong>PARAM\u00c8TRES ET SOUS-ROUTINES<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">L\u2019entr\u00e9e et la sortie de donn\u00e9es n\u00e9cessaires au\nfonctionnement d\u2019une sous-routine, peut se d\u00e9rouler de quatre fa\u00e7ons&nbsp;:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>En passant par les registres (A, X et \/ ou Y). C\u2019est la meilleure m\u00e9thode et la plus performante lorsqu\u2019il s\u2019agit de donn\u00e9es constitu\u00e9es d\u2019un ou deux octets<\/li><li>En passant par des variables en RAM. Cette m\u00e9thode est parfaite pour des donn\u00e9es qui doivent rester en RAM et qui doivent servir \u00e0 d\u2019autres routines. Elle est souvent utilis\u00e9e de mani\u00e8re conjointe \u00e0 la premi\u00e8re m\u00e9thode.<\/li><li>Les besoins en entr\u00e9es de la sous-routine peuvent \u00eatre int\u00e9gr\u00e9s au programme lui-m\u00eame, juste apr\u00e8s l\u2019instruction JSR (comme par exemple une cha\u00eene alphanum\u00e9rique \u00e0 afficher). Dans ce cas, la sous-routine utilise l\u2019adresse de retour stock\u00e9e sur la pile en guise d\u2019adresse de d\u00e9but des donn\u00e9es. Elle peut aussi utiliser un octet qui d\u00e9termine le nombre de donn\u00e9es ou un d\u00e9limiteur afin de savoir de combien d\u2019octets avancer l\u2019adresse de retour avant d\u2019ex\u00e9cuter l\u2019instruction RTS (et d\u2019\u00e9viter que le processeur ne traite les donn\u00e9es comme une instruction).<\/li><li>En passant par la pile mat\u00e9riel.<ul><li>Pile en page 1&nbsp;: le programme appelant empile la (ou les) donn\u00e9es gr\u00e2ce \u00e0 PHA, puis r\u00e9cup\u00e8re le (ou les) r\u00e9sultats gr\u00e2ce \u00e0 PLA, au retour de la sous-routine.<\/li><li>Pile virtuelle en page 0&nbsp;: Idem pr\u00e9c\u00e9demment, avec une pile de donn\u00e9es diff\u00e9rentes de la pile mat\u00e9rielle, ce qui peut faciliter certaines op\u00e9rations sur la pile et l\u2019adressage indirect. Par exemple, la pile de donn\u00e9es peut \u00eatre utilis\u00e9e dans un processus en plusieurs \u00e9tapes pour calculer une adresse, adresse qui \u00e0 son tour peut \u00eatre utilis\u00e9e pour un acc\u00e8s indirect \u00e0 un octet dans un tableau pour faire un calcul ou une op\u00e9ration logique.<\/li><li>Pile en RAM&nbsp;: Idem pile virtuelle en page 0, mais pouvant typiquement servir pour des nombres en virgule flottante autres que des adresses n\u00e9cessitant les modes d\u2019adressage disponibles en page 0.<\/li><\/ul><\/li><\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Examinons un\nexemple dans lequel il s\u2019agit d\u2019utiliser la pile mat\u00e9riel pour une donn\u00e9e\nd\u2019entr\u00e9e. Dans cet exemple, notre sous-routine transforme un demi-octet\nhexad\u00e9cimal en octet ASCII, avec un octet en entr\u00e9e et un octet en sortie, le\ntout stock\u00e9 sur la pile mat\u00e9riel.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>&lt;do_stuff&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Get the nybble into A.&nbsp; Allowable value is 0-F.\nPHA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  ; Other code can be put between the PHA and the PLA, as long\nJSR&nbsp; <\/code><strong><code>NYB2ASCII<\/code><\/strong><code> ; as it doesn't care if NYB2ASCII overwrites A and X. The\nPLA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; subroutine's input and output are protected on the stack though.\n&lt;do_stuff&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Do something with the ASCII output, like add it to a string, display it, etc..<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">La sous-routine NYB2ASCII pourrait ressembler \u00e0 ceci.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>NYB2ASCII<\/strong>:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">TSX<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">LDA&nbsp; $103,X&nbsp;&nbsp;&nbsp;&nbsp; ; 103 reaches past the return address, to\nthe input parameter.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">CMP&nbsp; #$0A&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n; Anything below $0A will end up in the $30&#8217;s.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">CLC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; CLC before the BMI so we only\nhave to do it once.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">BMI&nbsp; n2a1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n; For 9 or less, skip the next instruction.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">ADC&nbsp; #7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; $0A becomes $11, $0B becomes $12,\netc..&nbsp; C is still clear.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;n2a1:&nbsp;\nADC&nbsp; #$30&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Whether the 7 got added above or not,\nthis gives the ASCII.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">STA&nbsp; $103,X&nbsp;&nbsp;&nbsp;&nbsp;\n; Put it on the stack, overwriting the input value.&nbsp; Note<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">RTS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; that we read and overwrote the\nbyte just behind the<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">; return address, leaving the return address\nundisturbed.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Voici un autre\nexemple dans lequel deux nombres de 16 bits non sign\u00e9s en entr\u00e9e sur la pile,\nsont multipli\u00e9s pour donner un nombre de 32 bits non sign\u00e9, en sortie sur la\npile.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">On empile tout\nd\u2019abord les deux nombres \u00e0 transformer, chacun avec le poids fort en premier,\nde sorte que le poids fort prenne l\u2019adresse la plus haute comme dans le\nfonctionnement habituel du 6502.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&lt;do_stuff&gt;&nbsp;&nbsp;&nbsp;&nbsp; ; Get high byte of first input,<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">PHA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; and push it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&lt;do_stuff&gt;&nbsp;&nbsp;&nbsp;&nbsp; ; Get low&nbsp;\nbyte of first input,<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">PHA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; and push it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&lt;do_stuff&gt;&nbsp;&nbsp;&nbsp;&nbsp; ; Get high byte of second input,<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">PHA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; and push it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&lt;do_stuff&gt;&nbsp;&nbsp;&nbsp;&nbsp; ; Get low byte of second input,<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">PHA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; and push it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">JSR&nbsp; UM_STAR&nbsp;&nbsp;\n; Now you can call the subroutine below that does the multiplying.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; If you pull the product off\nthe stack now, the byte order will be:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">PLA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; 2nd-highest byte<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&lt;do_stuff&gt;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">PLA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; high byte<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&lt;do_stuff&gt;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">PLA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; low byte<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&lt;do_stuff&gt;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">PLA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; 2nd lowest byte<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&lt;do_stuff&gt;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Selon les op\u00e9rations que vous souhaitez r\u00e9aliser ensuite,\nvous pouvez tr\u00e8s bien laisser le premier r\u00e9sultat sur la pile.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Si l\u2019op\u00e9ration\napr\u00e8s la multiplication des deux nombres est de calculer la racine carr\u00e9e pour\nen obtenir la raison g\u00e9om\u00e9trique, alors il convient de ne pas toucher \u00e0 la pile\ntant que cette seconde op\u00e9ration n\u2019est pas effectu\u00e9e (la raison g\u00e9om\u00e9trique\n\u00e9quivaut \u00e0 une moyenne logarithmique. La raison g\u00e9om\u00e9trique de 1 et 100 est de\n10, et non de 50,5).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pour acc\u00e9der aux\ndonn\u00e9es stock\u00e9es sur la pile sans les d\u00e9piler et dans l\u2019ordre de votre\npr\u00e9f\u00e9rence, vous pouvez continuer d\u2019utiliser X comme index de pile (ainsi que\nd\u00e9crit dans l\u2019exemple <strong>UM_STAR<\/strong> ci-dessous). En cas de TSX, vous devrez ajuster l\u2019index en\ntenant compte du fait que l\u2019adresse de retour n\u2019est plus sur la pile, et comme\nd\u00e9crit ci-apr\u00e8s, qu\u2019un PLA a d\u00e9plac\u00e9 les r\u00e9sultats sur la pile de $101,X \u00e0 $104,X.\nPar contre, sans TSX l\u2019index est toujours valide et pointe bien sur les bonnes\ndonn\u00e9es.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>UM_STAR<\/strong>: LDA #0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Unsigned, mixed-precision\n(16-bit by 16-bit input, 32-bit output)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PHA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; multiply.&nbsp; Add a variable byte to the stack,\ninitializing it as 0.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TSX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Now 101,X holds that new\nvariable, $102,X and $103,X hold the return address<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LSR $107,X&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;and $104,X to $107,X holds the\ninputs and later the outputs.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ROR $106,X<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FOR_Y&nbsp;\n16, DOWN_TO, 0&nbsp; ; Loop 16x.&nbsp; The DEY, BNE in NEXT_Y below will drop\nthrough on 0.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IF_CARRY_SET<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CLC<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PHA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Note that the PHA (and PLA below)\ndoesn&#8217;t affect the indexing.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LDA $101,X<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ADC $104,X<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STA $101,X<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PLA<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ADC $105,X<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; END_IF<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ROR<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ROR $101,X<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ROR $107,X<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ROR $106,X<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NEXT_Y<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STA $105,X<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PLA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Retrieve the variable\nbyte we added at the top, cleaning up the stack.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STA $104,X&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Again note that the PLA changed\nS but not X, so the $104 is still $104.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RTS<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Note&nbsp;: Dans de nombreux cas, il serait plus judicieux de nommer les\ndonn\u00e9es pr\u00e9sentes sur la pile, en utilisant la macro EQU, plut\u00f4t que de se\ncontenter de $101,X ou \u00e9quivalent.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Supposons\nmaintenant que vous ayez besoin d\u2019une sous-routine avec quatre octets en entr\u00e9e\net six octets en sortie.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Afin de servir de\nla pile mat\u00e9rielle pour deux donn\u00e9es suppl\u00e9mentaires en sortie, il faut donc\nr\u00e9soudre le probl\u00e8me de l\u2019adresse de retour qui ne sera pas en haut de la pile\nlors du RTS.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La meilleure\nm\u00e9thode consiste \u00e0 faire de la place sur la pile avant d\u2019appeler la\nsous-routine&nbsp;:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">PHA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Push two dummy bytes onto the\nstack to hold the<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">PHA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; positions open for outputs of\nthe subroutine called below.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&lt;do_stuff&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Prepare the subroutine input bytes to\nbe passed.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">JSR&nbsp; subroutine&nbsp;\n; Without changing the stack pointer, the subroutine<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">; can now give you two more bytes of output than\ninput.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Autre cas\npratique, celui o\u00f9 vous auriez besoin de plus de donn\u00e9es en entr\u00e9es qu\u2019en\nsortie.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dans ce cas, il suffit\nde d\u00e9piler les donn\u00e9es inutiles apr\u00e8s \u00eatre sorti de la sous-routine.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ainsi, pour\nrestaurer la hauteur de pile, faites&nbsp;:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&lt;do_stuff&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Set up inputs, reserve output byte\nplaces in stack, etc..<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">TSX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Mark the current stack position.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&lt;do_more_stuff&gt;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">JSR&nbsp; &lt;subroutine&gt;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&lt;do_stuff&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Handle outputs, etc..<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">TXS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Restore stack to the marker\nset earlier, possibly also<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">; to put certain outputs at the top.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u00c9videmment le\nregistre X ne devra pas \u00eatre modifi\u00e9 par la sous-routine, ou alors il faudra le\nsauvegarder \u00e0 son tour sur la pile.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Comme d\u00e9crit\npr\u00e9c\u00e9demment, la pile mat\u00e9riel n\u2019est pas la seule solution en tant que pile de\nstockage. Une pile en page z\u00e9ro (ZP) pr\u00e9sente par exemple l\u2019avantage de\ndisposer de modes d\u2019adressages suppl\u00e9mentaires.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Utiliser une autre\npile que la pile mat\u00e9riel permet aussi de r\u00e9soudre le probl\u00e8me suivant&nbsp;: admettons\nque la pile mat\u00e9riel en page 1 serve pour passer des param\u00e8tres \u00e0 une\nsous-routine qui elle-m\u00eame doit fournir des param\u00e8tres \u00e0 autre sous-routine.\nLors de l\u2019entr\u00e9e dans la seconde sous-routine, l\u2019adresse de retour se retrouve\ndonc d\u00e9sormais au sommet de la pile, tandis que les donn\u00e9es d\u2019entr\u00e9e sont\nd\u00e9cal\u00e9es vers le bas, ce qui donnera \u00e0 coup s\u00fbr des r\u00e9sultats erron\u00e9s.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Mettons en \u0153uvre\ncet exemple avec la sous-routine <strong>GEOMEAN<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>GEOMEAN<\/strong>: JSR&nbsp; UM_STAR&nbsp; ; Multiply two 16-bit unsigned inputs on the\nstack.&nbsp; Get 32-bit product.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JSR&nbsp;\nSQRT&nbsp;&nbsp; &nbsp;&nbsp;; Take a 32-bit input on the stack and get a\n16-bit output, leaving two<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RTS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; dummy bytes on stack (problem:\nGEOMEAN&#8217;s return addr is still on top!)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Supposons que vous commenciez par empiler $1234 sur la pile mat\u00e9riel\n(poids fort en premier, sur le dessus de la pile), puis que vous empiliez $5678\navant d\u2019appeler la sous-routine GEOMEAN.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Lorsque le\npointeur de programme attend la premi\u00e8re instruction apr\u00e8s PHA et TSX dans le\nprogramme UM_STAR, UM_STAR part \u00e0 la recherche du premier nombre \u00e0 multiplier ($1234\ndans notre exemple), cens\u00e9 se trouver aux adresses $106,X et $107,X, puis du\nsecond nombre ($5678 dans l\u2019exemple) qui se trouve aux adresses $104,X et\n$105,X. L\u2019adresse de retour se trouve quant \u00e0 elle index\u00e9e par $102,X et\n$103,X.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Il y a cependant\nmaintenant deux adresses de retour au sommet de la pile&nbsp;: celle qui a fait\nappel \u00e0 UM_STAR et celle qui a fait appel \u00e0 GEOMEAN. UM_STAR va donc ignorer\n$1234 et multiplier $5678 avec l\u2019adresse de retour de GEOMEAN, entra\u00eenant ainsi\nun r\u00e9sultat erron\u00e9 et l\u2019\u00e9crasement de l\u2019adresse de retour de GEOMEAN. C\u2019est le\nplantage assur\u00e9&nbsp;!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Vous vous\napercevez \u00e9galement que le fait d\u2019utiliser JMP au lieu de la paire\nd\u2019instruction JSR \/ RTS peut entra\u00eener des probl\u00e8mes d\u2019incompatibilit\u00e9 li\u00e9s \u00e0\nune mauvaise gestion des donn\u00e9es empil\u00e9es sur la pile mat\u00e9riel.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La pile en page z\u00e9ro permet de contourner ce genre de probl\u00e8me, tout\nsimplement parce que l\u2019adresse de retour n\u2019est pas empil\u00e9e sur cette derni\u00e8re.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">En plus de\nl\u2019adressage de la page z\u00e9ro qui est plus performant que celui de la pile\nmat\u00e9riel, signalons aussi&nbsp;les b\u00e9n\u00e9fices suivants :<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Inutile de replacer les param\u00e8tres d\u2019entr\u00e9e sur la pile sans\narr\u00eat, avec pour r\u00e9sultat imm\u00e9diat une ex\u00e9cution plus rapide des \u00e9tages de la\npile&nbsp;;<\/li><li>R\u00e9duction des effets li\u00e9s \u00e0 la r\u00e9cursivit\u00e9 (ce sujet sera\nabord\u00e9 dans un prochain article)&nbsp;;<\/li><li>Possibilit\u00e9 de placer plusieurs type (et quantit\u00e9) de\nvaleurs&nbsp;;<\/li><li>Code plus compact qui permet un meilleur fonctionnement car\nplus besoin de devoir empiler\/d\u00e9piler des param\u00e8tres lors de l\u2019appel de\nsous-routines.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Revenons\nmaintenant \u00e0 notre sous-routine qui transforme un demi-octet hexad\u00e9cimal en\noctet ASCII et voyons comment r\u00e9aliser cette transformation en utilisant une\npile ZP.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">X\nservira de pointeur de pile, initialis\u00e9 en d\u00e9but de programme pour indexer de\nla mani\u00e8re suivante $00,X.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pour\nempiler en page z\u00e9ro, il faut donc faire un DEX puis stocker en $0,X.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Voici\nce que donne la routine modifi\u00e9e pour la pile ZP&nbsp;:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&lt;do_stuff&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Get the nybble into A.&nbsp; Allowable value is 0-F.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">DEX<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">STA&nbsp; 0,X&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n; Other code can be put between the STA and the LDA, and<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">JSR&nbsp; NYB2ASCII&nbsp;\n; NYB2ASCII&#8217;s input and output are protected on the stack.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">LDA&nbsp; 0,X&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n; X must be preserved as the data stack pointer of course.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">INX<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&lt;do_stuff&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Do something with the ASCII output,\nlike add it to a string, display it, etc..<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Note&nbsp;: Si vous avez besoin\ndu registre X dans le reste de votre programme, il vous faudra le sauver sur la\npile mat\u00e9riel.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La sous-routine <strong>NYB2ASCII<\/strong>&nbsp;devient :<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>NYB2ASCII<\/strong>:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; (The initial TSX is no longer\nnecessary.)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LDA&nbsp;\n0,X&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Get the input\nparameter from the data stack.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CMP&nbsp;\n#$0A&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Anything below $0A\nwill end up in the $30&#8217;s.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CLC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; CLC before the BMI so we only\nhave to do it once.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BMI&nbsp;\nn2a1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; For 9 or less, skip\nthe next instruction.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ADC&nbsp;\n#7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; $0A becomes $11, $0B\nbecomes $12, etc..&nbsp; C is still clear.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;n2a1:&nbsp;\nADC&nbsp; #$30&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Whether the 7 got added above or not,\nthis gives the ASCII.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STA&nbsp;\n0,X&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Put it on the data\nstack, overwriting the input value.&nbsp; Note<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RTS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; that the return address is not\non this stack to worry about.<br><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Proc\u00e9dons selon la\nm\u00eame logique pour la sous-routine <strong>UM_STAR<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>UM_STAR<\/strong>: DEX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Add a stack byte to use\nas a temporary variable.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LDA&nbsp; #0<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STA&nbsp; 0,X&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; 0,X addresses the temporary\nvariable.&nbsp; These are in ZP.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LSR&nbsp; 4,X<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ROR&nbsp; 3,X<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FOR_Y&nbsp; 16, DOWN_TO, 0<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IF_CARRY_SET&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; The 1st time thru the loop, A needs 0;\nso don&#8217;t use STZ above.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CLC<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PHA<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LDA&nbsp; 0,X<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ADC&nbsp; 1,X<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STA&nbsp; 0,X<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PLA<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ADC&nbsp; 2,X<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; END_IF<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ROR<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ROR&nbsp; 0,X<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ROR&nbsp;\n4,X<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ROR&nbsp; 3,X<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NEXT_Y<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STA&nbsp; 2,X<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LDA&nbsp; 0,X<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STA&nbsp; 1,X<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; INX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Take back the stack byte\nwe used as a temporary variable.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RTS<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ici, un octet est empil\u00e9 sur la pile ZP gr\u00e2ce \u00e0 l\u2019instruction\nDEX (puis d\u00e9pil\u00e9 gr\u00e2ce \u00e0 INX), de la m\u00eame mani\u00e8re que pour PHA (puis PLA). La\npile ZP permet donc d\u2019\u00e9viter d\u2019avoir \u00e0 sauver\/restaurer l\u2019index X.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Il est en outre possible de se passer des instructions\nDEX\/INX en adressant le nouvel octet gr\u00e2ce \u00e0 $FF,X qui permet de rester en page\nz\u00e9ro et qui \u00e9conomise au passage 2 octets et 4 cycles d\u2019horloge.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Assurez-vous cependant de n\u2019avoir aucune sous-routine ou\ninterruption susceptible d\u2019\u00e9craser cet octet, car X semble indiquer que cet\nemplacement est libre.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La sous-routine <strong>GEOMEAN<\/strong> quant \u00e0 elle, peut d\u00e9sormais s\u2019\u00e9crire&nbsp;:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>GEOMEAN<\/strong>: JSR&nbsp; UM_STAR&nbsp;\n; Multiply two 16-bit unsigned inputs on the stack and get a 32-bit\nproduct.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JMP&nbsp;\nSQRT&nbsp;&nbsp;&nbsp;&nbsp; ; (JSR, RTS)&nbsp; Take a 32-bit input on the stack and get a\n16-bit output. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Voici dans le d\u00e9tail les avantages \u00e0 travailler avec des\npiles s\u00e9par\u00e9es&nbsp;:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Le nombre d\u2019octets\nentr\u00e9s est ind\u00e9pendant du nombre d\u2019octets sortis. En d\u2019autres termes, nul\nbesoin de nettoyer les octets de sortie factices ni de placer des octets\nfactices sur la pile&nbsp;;<\/li><li>En disposant de\ndonn\u00e9es s\u00e9par\u00e9es, les adresses de retour ne sont pas trait\u00e9es comme des\ndonn\u00e9es. Le param\u00e9trage devient implicite&nbsp;;<\/li><li>Une sous-routine\npeut faire appel \u00e0 une autre sous-routine sans avoir \u00e0 faire le m\u00e9nage sur la pile\nmat\u00e9riel (qui devient d\u00e9sormais la pile de retour)&nbsp;;<\/li><li>La pile mat\u00e9riel\nest maintenant disponible pour d\u2019autres usages tels que la gestion des limites\net des index de boucles (y compris des boucles imbriqu\u00e9es)&nbsp;;<\/li><li>L\u2019ajout d\u2019une\nnouvelle pile permet d\u2019augmenter l\u2019espace de stockage et d\u2019\u00e9viter un crash sur\nla pile mat\u00e9riel&nbsp;;<\/li><li>Gr\u00e2ce aux modes\nd\u2019adressages du 6502 en page z\u00e9ro (ZP,X), nous pouvons adresser la pile ZP tr\u00e8s\nfacilement.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Voyons justement comment mettre \u00e0 profit les modes\nd\u2019adressage ZP,X dans l\u2019exemple de routine de d\u00e9placement suivante.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Nous appellerons cette routine <strong>CMOVE<\/strong>, pour &#8220;character move&#8221;.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Avant de faire tourner cette routine, nous pla\u00e7ons six octets\nsur la pile ZP, sous la forme de 3 nombres de 16 bits (poids fort sur l\u2019adresse\nla plus haute dans chaque cas)&nbsp;:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Adresse de d\u00e9part<\/li><li>Adresse de\ndestination<\/li><li>Taille de m\u00e9moire\n\u00e0 d\u00e9placer (pouvant aller jusqu\u2019\u00e0 quelques dizaines de milliers d\u2019octets)<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>CMOVE<\/strong>:&nbsp; LDA&nbsp;\n0,X&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; &#8220;See-move&#8221;\nCharacter (memory) move&nbsp; ( from to len &#8212;\n)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ORA&nbsp;\n1,X<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BEQ&nbsp; POP3&nbsp;&nbsp;&nbsp;&nbsp;\n; If remaining length is 0, branch to POP3 which is just 6 INX&#8217;s, then\nRTS.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LDA&nbsp; (4,X)&nbsp;&nbsp;&nbsp;\n; Get a byte and<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STA&nbsp; (2,X)&nbsp;&nbsp;&nbsp;\n; transfer it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; INC&nbsp; 4,X<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BNE&nbsp; cm1$<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; INC&nbsp; 5,X&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n; Increment the source addr<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;cm1$:&nbsp; INC&nbsp;\n2,X<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BNE&nbsp; cm2$<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; INC&nbsp; 3,X&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n; and the destination addr,<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;cm2$:&nbsp; DEC&nbsp;\n0,X&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; decrement the count\nleft,<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LDA&nbsp; 0,X<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CMP&nbsp; #$FF<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BNE&nbsp; CMOVE<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DEC&nbsp; 1,X<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; and go back up for\nanother loop.&nbsp; If we&#8217;re\ndone,<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BRA&nbsp; CMOVE&nbsp;&nbsp;&nbsp;\n; that fact will be caught in the first three lines (BRA is for 65c02\nonly and stands for Branch Always).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Quand faut-il\n\u00e9viter l\u2019emploi d\u2019une pile pour l\u2019usage de param\u00e8tres d\u2019entr\u00e9es \/ sorties dans\ndes sous-routines&nbsp;?<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">D\u00e9placer des donn\u00e9es dans une pile requiert du temps\nprocesseur.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Aussi, si vous devez manipuler une grande quantit\u00e9 de\ndonn\u00e9es, comme une cha\u00eene alphanum\u00e9rique, un tableau ou m\u00eame une matrice,\nplacez l\u00e0 ailleurs en m\u00e9moire et indiquez son adresse de stockage sur la pile.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>R\u00c9CURSIVIT\u00c9<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Une sous-routine peut pr\u00e9senter la particularit\u00e9 d\u2019\u00eatre\nr\u00e9cursive, \u00e0 savoir qu\u2019elle peut s\u2019appeler elle-m\u00eame \u00e0 de nombreuses reprises.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Afin d\u2019\u00e9viter que ce genre de sous-routine ne reboucle\nind\u00e9finiment, entra\u00eenant une surcharge de la pile mat\u00e9riel, il faut pr\u00e9voir une\ncondition qui permette de quitter la sous-routine au bout de x boucles\nr\u00e9cursives.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Lorsque cette (ou ces) condition(s) est respect\u00e9e, on quitte\nalors la sous-routine par une s\u00e9rie de RTS.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Chaque sous-routine nidifi\u00e9e (imbriqu\u00e9e) peut disposer de ses\npropres variables ayant&nbsp; pourtant des\nnoms semblables.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Prenons l\u2019exemple de la fonction de Fibonacci qui est\nutilis\u00e9e en calculs financiers, lors de la g\u00e9n\u00e9ration de nombres pseudo\nal\u00e9atoires, dans des algorithmes de tri et de recherche ou encore pour la\ncompression de fichiers audio.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">fiboIO:&nbsp;&nbsp;&nbsp; SETL $103&nbsp;&nbsp;&nbsp;\n; For clarity, give names to the locals.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">fiboTemp:&nbsp; SETL $102&nbsp;&nbsp;&nbsp; ; (Record of X will be at $101,X.)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>FIBO<\/strong>:&nbsp; CMP&nbsp;\n#2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Test the input.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BCC&nbsp; end&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n; If it&#8217;s 0 or 1, so is the output, so just end.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; This\nprevents endless nesting, too.&nbsp;\nOtherwise,<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PHA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; create local variable fiboIO,\nand store A there.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PHA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Create another local variable\nbyte, fiboTemp.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;; (Its initial value\ndoesn&#8217;t matter.)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PHX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Push X too, to protect the\ncalling routines.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TSX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Prepare X to use for\nstack-relative addressing.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DEA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Get the n-1 term<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JSR&nbsp; FIBO&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n; and calculate the number for it (recursing here)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STA&nbsp; fiboTemp,X&nbsp;\n; and store its result in local variable fiboTemp.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LDA&nbsp; fiboIO,X<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DEA<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DEA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Now get the n-2 term<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JSR&nbsp; FIBO&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n; and calculate the number for it (recursing here).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CLC<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ADC&nbsp; fiboTemp,X&nbsp;\n; Add those two together, and<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STA&nbsp; fiboIO,X&nbsp;&nbsp;&nbsp;\n; store the answer.&nbsp; Don&#8217;t forget\nthe &#8220;,X&#8221;!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Note that\nthere is no looping.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PLX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Restore X for the calling\nroutines.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PLA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Pull fiboTemp off the stack and\ndiscard it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PLA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Pull the answer (fiboIO) off\nthe stack into A.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">end:&nbsp;&nbsp; RTS<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Cette sous-routine tient sur 34 octets et n\u2019utilise pas la\nRAM pour le stockage, hormis bien s\u00fbr la pile mat\u00e9riel.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La donn\u00e9e d\u2019entr\u00e9e doit rester inf\u00e9rieure \u00e0 14 car la donn\u00e9e\nde sortie est sur 8 bits et le nombre de Fibonacci pour 13 est 233.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Avec une r\u00e9ponse sur deux octets ou plus, nous pourrions\navoir une donn\u00e9e d\u2019entr\u00e9e plus grande sans manquer de place sur la pile, m\u00eame\nsi ce genre de sous-routine en consomme beaucoup.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La place disponible sur la pile est largement suffisante pour\ndes sous-routines simples, mais rappelons que les routines r\u00e9cursives ne sont\npas des routines normales.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u00c0 suivre.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>PARAM\u00c8TRES ET SOUS-ROUTINES L\u2019entr\u00e9e et la sortie de donn\u00e9es n\u00e9cessaires au fonctionnement d\u2019une sous-routine, peut se d\u00e9rouler de quatre fa\u00e7ons&nbsp;: En passant par les registres (A, X et \/ ou Y). C\u2019est la meilleure m\u00e9thode et la plus performante lorsqu\u2019il s\u2019agit de donn\u00e9es constitu\u00e9es d\u2019un ou deux octets En passant par des variables en RAM. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[346,22],"tags":[376,658],"class_list":["post-796","post","type-post","status-publish","format-standard","hentry","category-assembleur","category-ceomag","tag-376","tag-ceomag350"],"_links":{"self":[{"href":"https:\/\/oric.bqtt.net\/index.php\/wp-json\/wp\/v2\/posts\/796","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/oric.bqtt.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/oric.bqtt.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/oric.bqtt.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/oric.bqtt.net\/index.php\/wp-json\/wp\/v2\/comments?post=796"}],"version-history":[{"count":0,"href":"https:\/\/oric.bqtt.net\/index.php\/wp-json\/wp\/v2\/posts\/796\/revisions"}],"wp:attachment":[{"href":"https:\/\/oric.bqtt.net\/index.php\/wp-json\/wp\/v2\/media?parent=796"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/oric.bqtt.net\/index.php\/wp-json\/wp\/v2\/categories?post=796"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/oric.bqtt.net\/index.php\/wp-json\/wp\/v2\/tags?post=796"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}