-------------------------------------------------------------------
Programmation assembleur - Auteur: HPmƒd - HPisteurs
recopi‚ de HPisteur par Manu - www.chez.com/manuhp
-------------------------------------------------------------------

8. Programmation (Meta instruction de bases).

 8.1. Introduction
        Vous devez maintenant savoir quelles sont les vraies difficult‚s de la
    programmation en assembleur: la traduction d'algos.
    Dans ce chapitre, je vais vous commenter une s‚rie de 'meta instruction'
    standard. Ainsi, vous n'aurez pas … ‚tudier ces instructions et …
    retrouver leur algo. Elles deviendront des instructions 'connues' c'est
    … dire pratiquement des instructions de base (pour votre esprit) de
    l'assembleur HP.

8.2. Initialisation, retour au RPL, PUSH et POP sur la pile.

 8.2.1. Les registres RPL.
        Le RPL utilise plusieurs registres du SATURN pour stocker des informa-
   tions trŠs utiles. Il convient … la sortie de tout programme de laisser ces
   registres … la valeur o— ils ‚taient en entr‚e sous peine de memlost. Ces
   registres sont D1, D0, Ba et Da.
   D1 pointe sur la premiŠre adresse de la pile.
   D0 pointe sur l'instruction RPL suivante … ex‚cuter.
   Da contient une estimation de la m‚moire libre en case de pile.
   Ba contient l'adresse de la fin de la pile de retours RPL.

 8.2.1.1. D1
        D1 pointe sur le premier niveau de la pile RPL. Pour comprendre exac-
   tement … quoi cela correspond, il faut connaŒtre la structure de la pile
   RPL de la HP.
    @D1+30 ->  7:  @Objet7
    @D1+25 ->  6:  @Objet6
    @D1+20 ->  5:  @Objet5
    @D1+15 ->  4:  @Objet4
    @D1+10 ->  3:  @Objet3
    @D1+5  ->  2:  @Objet2
    @D1    ->  1:  @Objet1
   En faisant une lecture sur un champ A en D1, on r‚cupŠre l'adresse de l'objet
   du niveau 1 de la pile. C'est … dire qu'en faisant
    A=DAT1 A
    D1=A
   D1 pointe sur le d‚but de l'objet du niveau 1 de la pile. Il faut alors con-
   naŒtre la structure des objet pour pouvoir l'utiliser. Le fond de la pile est
   marqu‚ par un #00000h. C'est … dire que si on lit l'adresse 0, c'est que l'on
   est … la fin de la pile. Il faut noter que plusieurs niveaux de la pile peuvent
   pointer le mˆme objet. Si on modifie le contenu de objet dont l'adresse est au
   niveau 1 et que cet objet est aussi pointe au niveau 2, cette modification
   affectera l'objet des deux niveaux.

 8.2.1.2. D0
   D0 pointe sur l'adresse de la prochaine instruction RPL … ex‚cuter.
   D0 est le PC du RPL.

 8.2.1.3. Ba
        Ba contient l'adresse du haut de la pile de retours RPL. Dans cette
   pile, le systeme stocke les adresses de retour de programmes RPL.
   C'est … dire qu'… chaque fois qu'il y a ouverture d'un programme RPL
   ($02D9D), le systeme empile l'adresse de retour qu'il d‚pile … la sortie.
   Cette pile est dans l'autre sens par rapport … la pile RPL. Ba contient
   donc l'adresse de la premiŠre case libre. Pour passer … la case … la case
   pr‚cedente, il faut faire B=B-5 A.

 8.2.1.4. Da
	Da contient une estimation de la m‚moire libre en cases de 5 quartets,
   c'est … dire une estimation du nombre de case de pile que l'on peut cr‚er.
   Cette m‚moire libre se trouve entre Ba et D1. Pour cr‚er un ‚tage de pile
   RPL, on fait
     D=D-1 A
     GOC .Insufisant_Memory
     D1=D1-5
   D1 pointe alors sur la nouvelle case. Il ne faut alors pas oublier de g‚rer
   le cas de m‚moire insuffisante.

 8.2.2. Initialiser et quitter un programme assembleur.
	Il faut donc … l'initialisation sauver les registres et les recup‚rer
   … la fin. Il faut ensuite continuer l'‚xecution … l'instruction RPL suivante.
   A l'initialisation, le plus pratique est de sauvegarder les registres D0,
   D1, Ba et Da. Pour ce faire, 4 places sont reserv‚es en RAM r‚serv‚e.
   Il y a mˆme une routine en ROM qui effectue la  sauvegarde: GOSBVL 0679B.
   Elle modifie D0 et Ca.
   De mˆme pour 'd‚sinitialiser'; on utilise GOSBVL 067D2 qui r‚cupŠre les
   valeurs stock‚es de D1, D0, Ba et Da. Il faut ensuite effectuer en retour
   au RPL. Ceci se fait par
      A=DAT0 A  %Aa contient l'adresse de la prochaine instruction RPL.
		%C'est … dire l'adresse de l'adresse de la routine
		%assembleur a ex‚cuter pour ex‚cuter l'instruction RPL.
     D0=D0+ 5   %On fait pointer D0 sur l'adresse de l'instruction RPL
		%suivante de la suivante.
     PC=(A)     %On branche PC … l'adresse de la routine assembleur …
		%l'ex‚cution de l'instruction RPL
   On appele cette s‚quence de 3 instruction le retour au RPL bien que ce soit
   plut“t la continuation de RPL.
   (NDGQR(Note Du Gars Qu'aRecopi‚) on peut remplacer cette s‚quence par un
   GOVLNG 12002)
   Il est ‚vident que si le but du programme ‚tait de modifier l'ex‚cution du
   programme RPL en cours, ou de manipuler la pile, on ne fera pas de save et
   load regs, il suffit de renvoyer D1 5 quartets plus loin.
     D1=D1+ 5      %Le premier ‚l‚ment de la pile est ignor‚
     D=D+1 A       %Il y a une case m‚moire de plus vu que l'on vient d'en                 %lib‚rer une.
     A=DAT0 A      %Retour au RPL
     D0=D0+ 5
     PC=(A)
   Comme vous pouvez le voir, je n'ai pas fait de sauvegarde des registres RPL
   car le but du programme ‚tait justement de les modifier.
   Voyons le SWAP. Il faut que j'inverse l'adresse du niveau 2 et celle du
   niveau1.
     A=DAT1 A      %Aa:@objet niveau 1
     D1=D1+ 5      %D1:niveau 2
     C=DAT1 A      %Ca:@objet niveau 1
     DAT1=A A      %Niveau 2:@objet niveau 1. Le niveau 2 contient donc            %l'objet du niveau 1
     D1=D1- 5      %D1: niveau 1
     DAT1=C A      %niveau 1:@objet niveau 2. Le niveau 1 contient l'adresse               %de l'objet du niveau 2.
     A=DAT0 A      %Retour au RPL.
     D0=D0+ 5
     PC=(A)
   Et voila pour le SWAP.
   On finit par le DUP qui est le plus compliqu‚. Il faut cr‚er une nouvelle
   case m‚moire et y mettre l'adresse de l'objet du niveau 1.
     D=D-1 A       %On enlŠve une case m‚moire
     GOC .Insufisant_Mem   %Si carry: pas assez de m‚moire
     C=DAT1 A      %Ca:@objet 1
     D1=D1- 5      %D1:@niveau -1 qui deviendra
     DAT1=C A      %On y met l'adresse de l'objet de l'ancien niveau 1
     A=DAT0 A
     D0=D0+ 5
     PC=(A)
   Et voil… poue le DUP.
   On finit avec le REVn, ce n'est pas une instruction RPL. Elle retourne les
   N premiers niveaux de la pile. N ‚tant un entier au niveau 1 de la pile.
   L'algo est simple, c'est le mˆme que celui de retournement d'un tableau.
          FOR i=1 TO n/2
          {
                a=T[i]
                T[i]=T[n-i+1]
                T[n-i+1]=a
          }
   Ici, le tableau c'est la pile, un tableau de case de 5 quartets. Il suffit
   en fait de faire un SWAP entre les niveaux i et N-i+1. Pour ce faire, on
   met 1 pointeur au d‚but de la pile (i) un pointeur en fin de pile (n-i+1)
   et on rapproche les pointeurs.
   Commen‡ons par la lecture de l'entier (expliqu‚e dans le paragraphe suivant).
        GOSBVL 0679B    %on vas se servir de D1, D0 et Ba.
                        %Il faut donc que je sauve les registres.
        A=DAT1 A
        D1=D1+ 5        %D1: niveau 2: premier niveau … retourner.
        D0=A
        D0=D0+ 10
        A=DAT0 A        %Aa: entier du niveau 1. cf structure des #
        B=A A           %Ba:n
        %Il faut maintenant initialiser un pointeur sur le dernier niveau:
        %le niŠme. Son adresse est D1+n*5-5.
        A=A+A A         %Multiplication par 5, cf. page
        A=A+A A
        A=A+B A
        CD1EX           %C=D1 instruction inexistante
        D1=C            %donc … d‚composer
        A=A+C A         %A:@niveau n+1
        D0=A            %D0: niveau n+1
        BSRB A          %Ba: n/2
        B=B-1 A         %On utilise un GONC
        GOC .Fin
        *.Boucle
          D0=D0- 5      %Niveau n
          A=DAT1 A      %@obj 1
          C=DAT0 A      %@obj n
          DAT1=C A      %Niv 1=Niv n
          DAT0=A A      %Niv n=Niv 1
          D1=D1+ 5      %Niveau 2
        B=B-1 A         %Boucle
        GONC .Boucle
        *.Fin
        GOSBVL 067D2
        D1=D1+5         %On drop l'entier
        D=D+1 A         %Fin du DROP
        A=DAT0 A        %retour au RPL
        D0=D0+ 5
        PC=(A)
   Magnifique non!

8.2.4. Prendre un ‚l‚ment de la pile
	Je ne vais pas vous expliquer comment prendre un ‚l‚ment sur la pile
   pour la bonne raison que cela d‚pend de l'‚l‚ment en question. Pour le faire
   il faudra connaŒtre la structure de cet ‚l‚ment. Ce chapitre vous expliquera
   comment initialiser un pointeur sur l'objet du niveau 1 de la pile (ou d'un
   autre niveau).
   Il faut d'abord r‚cup‚rer l'adresse de cet ‚l‚ment. Pour ce faire il faut
   initialiser un pointeru au d‚but la pile. Si on est en d‚but de programme
   assembleur, D1 pointe sur cette pile, sinon, il faut aller r‚cup‚rer la
   valeur de D1 l… o— la routine en 0679B l'a sauv‚e, c'est … dire en 806F8.
        D1= 806F8     %D1: @@pile = @@@ 1er objet de la pile
        A=DAT1 A      %A:@pile
        D1=A          %D1: pile
        A=DAT1 A      %A: @objet
        D1=A          %D1: objet
   D1 pointe maintenant sur le prologue de l'objet du niveau 1. On peut maintenant r‚aliser un test pour v‚rifier si cet objet est bien du type voulut.
        A=DAT1 A      %Aa: prologue de l'objet
        LC 02A2C      %Ca: prologue de string. A vous de mettre le prologue           %voulut
        ?A=C A        %l'objet est du type d‚sir‚
        GOYES .Bon_Type
              GOSBVL 067D2    %Load Reg
              LC 00202        %ERRN de Bad_Arg_Type
              GOVLNG 10F80    %Ca doerr
        *.Bon_Type

8.2.5. Mettre un ‚l‚ment sur la pile
	L… ca se complique. Pour mettre un objet sur la pile il faut disposer
   de cet objet, c'est … dire le construire. Pour le construire, il faut avoir
   une zone de m‚moire qui lui est r‚serv‚e. Donc il faut d'abord r‚server de
   la m‚moire puis aprŠs cr‚er une case de pile ou mettre son adresse. Mais
   commen‡ons par le commencement. Essayons de transformer en Entier en caractŠre.
   C'est … dire que notre programme mettra dans la pile un caractŠre de code
   ASCII les deux quartets de poids faible de l'entier en argument. Mais
   r‚alisons d'abord la lecture de ces deux quartest, c'est … dire la lecture
   et le DROPing de l'entier du niveau 1.
        A=DAT1        %Lecture de l'adresse
        D1=D1+ 5      %DROP
        D=D+1 A
        GOSBVL 0679B  %Save Regs
        D1=A  %D1: prologue de l'entier
        D1=D1+ 10     %D1: contenu de l'entier
        C=DAT1 B      %Lecture des deux quartets
        RSTK=C        %Sauvegarde des 2 quartets
        LC 00007      %on va r‚server 7 quartets pour le caractŠre.
        GOSBVL 039BE  %R‚servation de Ca quartets, adresse de la zone
                      %reserv‚e en D0
        LC 029BF      %prologue de caractŠre
        DAT0=C A      %on poke le prologue
        D0=D0+ 5      %on pointe sur la zone ou il faut mettre la valeur du chr
        C=RSTK        %on recupŠre la valeur sauvegard‚e
        DAT0=C B      %et on la poke
        D0=D0- 5      %on r‚cupŠre l'adresse
        AD0EX %de d‚but du caractŠre
        GOSBVL 067D2  %Load (ne modifie pas Aa)
        D=D-1 A       %y a t-il assez de place?
        GOC .Ins      %M‚moire insuffisante
        D1=D1- 5      %on ajoute un niveau
        DAT1=A A      %on y met l'adresse du caractŠre
        A=DAT0 A      %retour au retour
        D0=D0+ 5
        PC=(A)
        *.Ins
        LC 00001              %ERRN de Insufisant memory
        GOVLNG 10F80  %Ca doerr

8.3. Math‚matique
 8.3.1. Stocker un nombre
	Il existe trois sortes de nombres en informatique, ou plut“t trois
   moyens de repr‚senter un nombre. Le format entier, le format virgule fixe
   et le format virgule flottante.
   Le format entier est le stockage classique en base 2. C'est … dire que le
   bit n a un poids de 2^n (NDGQC: ^ signifie puissance). Pour repr‚senter les
   entiers sign‚s, on a recours … deux techniques diff‚rentes: le compl‚ment …
   deux et la marque de signe.
   Dans la premiŠre, on peut repr‚senter sur n bits les entiers de -2^(n-1) …
   2^(n-1)-1. Un entier positif est stock‚ normalement, et son oppos‚ est
   calcul‚ par compl‚ment … 2, c'est … dire grƒce … l'instruction A=-A A. On
   reconnaŒt si un entier est n‚gatif ou positif grƒce … la valeur du dernier
   bit. S'il est … 0, l'entier est n‚gatif. Il faut noter que les additions et
   les soustractions marchent trŠs bien.
   La deuxiŠme technique, la sign‚e se sert du dernier bit pour indiquer le
   signe. Les op‚rations math‚matique sont un peu plus complexe. De plus le
   nombre 0 est repr‚sent‚ 2 fois. +0 et -0.
   Le format … virgule fixe est obtenu en prenant des entiers en repr‚sentation
   sign‚e et en disant qu'il repr‚sentent le r‚el … un facteur multiplicatif
   prŠs. C'est … dire qu'au lieu de stocker le r‚el on le stocke sous forme
   entiŠre en sachant que l'on retrouve le r‚el en faisant une division. Par
   exemple, on peut prendre un facteur multiplicatif de 256. Il faut choisir
   ce facteur en fonction de l'ordre des r‚els avec lesquels on doit travailler.
   Le dernier mode de stockage, en virgule flottante correspond aux r‚els
   classiques. Le stockage est du type: Signe, mqtrice, exposant. Les op‚rations
   sur les flottants sont trŠs complexes. Il y a des problŠmes de normalisation
   entres autres. Il est peu ais‚ de s'y attaquer en assembleur.
   De toutes fa‡on, … par si on veut faire des prgrammes math‚matiques, on se
   sert exclusivement d'entiers. Mˆme pour tracer Mandelbrot, on travail en
   virgule fixe ce qui revient presque … travailler sur des entiers.

 8.3.2. Lire un nombre
	Par lire un nombre, j'entends l'algo pour lire un nombre en hexa ou
    en d‚cimal dans un chaŒne de caractŠres, donc en ASCII et le retranscrire
    en entier dans un registre. Voyons d'abord le cas de la lecture d'un nombre
    HEXA.
   1. Lire un nombre HEXA
	L'algo est simple. Etant donn‚ que la lecture commence par les digits
      de poids fort (on ‚crit de gauche … droite), le systŠme vas ˆtre:
         Lecture d'un digit,
         Multiplication par la base
         on continue avec l'autre digit.
      Ainsi, les problŠmes de modulo, de nombres de digits … lire sont r‚gl‚s.
      Mais si on est au dernier digit, on a multiplie une fois de trop par la
      base, il va donc falloir diviser par la base. Pour une base 16, cela ne
      pose pas problŠme, mais en base 10, ce sera plus embˆtant. On modifie
      donc l'algo en:
         Result=0
         While encore digit
         {   Result=Result*base
             Result=Result+digit
         }
      Ce qui donne en assembleur, en lisant la chaine en D1:
         B=0 A   %Ba: Result
         *.Boucle
            A=DAT1 B     %Lecture du chr ASCII
            LC 30        %Chr de 0
            A=A-C B      %On essaye de r‚cup‚rer la valeur du digit en
                         %fonction du code ASCII
            GOC .fin     %Il n'y a pas de digits valides en dessous de 30
            LC 09        %on teste si l'on est au dessus de 9
            ?A<C B
            GOYES .Pas_A_F
               A=A-7 B   %on red‚cale
            *.Pas_A_F    %Ap contient maintenant le digit Hexa
                         %repr‚sent‚ par le chr.
            LC 10        %C'est le maximum.
            ?A>C B       %On est dessus de F
            GOYES .Fin
            BSL A        %B=B*16
            B=A P        %Result=Result+digit
            D1=D1+2      %on passe au chr suivant
         GOTO .Boucle
         *.Fin
	
   2. Lecture d'un nombre Decimal
         L…, il y a moins de problŠme pour r‚cupŠrer le digit que pour la lec-
     ture HEXA car les digits permis sont entre 0 et 9, mais il faut faire une
     multiplication par 10.
	B=0 A		%Ba: Result
	*.Boucle
	  A=0 A
	  A=DAT1 B	%Lecture du chr ASCII
          LC 30         %chr de 0
	  A=A-C B	%on essaye de re‚cup‚rer la valeur du digit en
			%fonction du code ASCII
	  GOC .fin	%il n'y a pas de digits valides en dessous de 30
          LC 09         %c'est le maximum
	  ?A>C B	%On est au dessus de 9: fin
	  GOYES .fin
		C=B A		%Result=Result*10
		C=C+C A
		C=C+C A
		B=B+C A
		B=B+B A
		BSL A		%B=B*16
		B=A P		%Result=Result+digit
                D1=D1+2         %on passe au chr suivant
	  GOTO .Boucle
	  *.fin
     Et voila. Je pr‚cise que le resultat est dans Ba.

 8.3.3. Addition (virgule flottante).
	Je vais juste expliquer le principe. Mais d'abord voyons le stockage
    d'un entier.
    L'exposant est un entier relatif. On utilise g‚n‚ralement un stockage
    en compl‚ment … 2. Le signe est un bit qui indique si le r‚el est positif
    ou n‚gatif.
    La mantisse est comprise entre 1 et 1/base. C'est … dire que son premier
    digit doit ˆtre non nul.
    Le r‚el est 'calcul‚' par Mantisse*BaseExposnt
    Pour faire une addition entre deux r‚els, il faut tout d'abord les
    normaliser, c'est … dire mettre le plus petit au mˆme exposant que le plus
    grand. il faut mettre les digits de mˆme poids en face. Puis, il faut
    teste les signes pour voir si on doit faire une addition ou une
    soustraction.
    Il faut ensuite effectuer cette op‚ration.
    Il faut ensuite renormaliser. En effet, s'il y a eu une retenue, il faut
    mettre le bon signe, il faut redecaler la mantisse le cas ‚ch‚ant.

 8.3.4 Addition (entier relatif)
	La c'est trŠs simple. En compl‚ment … 2, il suffit de faire A=A+B A.
    Il faut noter que l'on travaille dans (NDGQR: l… je sais pas c bizarre ca
    veut rien dire)... C'est …n dire modulo un certain nombre. Il en r‚sulte
    un 'bouclage'. Max integer+1=Min integer. Si on veut faire un contr“le
    d'overflow, il faut d‚composer l'addition, ou augmenter temporarirment
    le nombre de digits pour pouvoir tester aprŠs l'addition si on est pas
    pass‚ sur des chiffres inrepr‚sentable dans le format choisit.

 8.3.5. Multiplication par une constante
        Le principe de la multiplication du contenu d'un registre par une
    constante est de d‚composer cette multiplication en addition et en
    multiplications par une puissance de 2. Ainsi, une multiplication par 10
    peut ˆtre ‚crite sous la forme:
	A*10=(A*4+A)*2   qui se programmerait:
	C=A A
	A=A+A A	%A=A*2
	A=A+A A	%A=A*4
	A=A+C A	%A=A*4+A=A*5
	A=A+A A	%A=(A*4+A)*2=A*10
    De mˆme pour une multiplication par 15 on ferait
	C=A A
	ASL A		%A=A*16
	A=A-C A	A=A*16-A=A*15
    Ceci pour vous montrer que l'on peut utiliser la soustraction.
    Pour une multiplication par #27h on ferait A=(A*32)+A*8-A donc
	C=A A
	A=A+A A
	A=A+A A
	A=A+A A	%A=A*8
	C=A-C A	%C=A*7
	A=A+A A
	A=A+A A	%A=A*32
	A=A+C A	%A=A*32+A*7=A*(#27h)

 8.3.6. Division par une constante
	Le principe est simple, on 'approxime' 1/N par n'/2b. Le seul problŠme
    est de calculer n' et b. b d‚pend de la pr‚cision que l'on veut avoir. Et
    n'=2b/N. Evidemment, n' ne sera pas un entier, on fera donc un arrondi.
    Il convient ensuite de diviser n' par 2b pour voir si l'approximation est
    bonne. Prenons l'exemple de la division par 10. Je choisi b=8.
    n'=256/10=25,6=26. Donc je r‚alise une division de 9,84 au lieu de 10. Il
    convient alors de savoir si cette approximation est suffisante. Ici, pour
    543, j'obtient 55,15 au lieu de 54. Pour 200, j'obtient bien 20, pour 400
    j'obtient bien 40. Je suis donc pr‚cis jusqu'… … peut prŠs 400. A moi de
    voir si je d‚sire plus de pr‚cision et d'augmenter b en cons‚quence.
	C=A A		%Multiplication par #1Ah (26)
        C=C+C A         %C=C*10 A
	C=C+C A
	C=C+A A
	C=C+C A
	ASL A		%A=A*16 A
        A=A+C A         %A=A*26 A
	ASR A		%A=A/256
	ASR A

 8.3.7. Multiplication (principe et entiŠre)
	On se sert de la multiplication … d‚calage dite aussi multplication
    indienne. Le principe est le suivant.
       A*B=B0*A + B1*A*2 + B2*A*4 .... + Bn*A*2^n   o— Bn est le bit n de B.

    Cela donne sur HP:
	B=0 A		%Ba: somme partielle
	*.Boucle
	  ?ABIT=0 0	%impair
	  GOYES .Im
              B=B+C A   %on somme si le bit est … 1
	  *.Im
	  ASRB A	%on passe au bit suivant
	  C=C+C A	%on multiplie par 2
        ?A#0 A          %il reste encore des bits?
	GOYES .Boucle
    Ceci r‚alise donc la multiplication de A*C et met le resultat dans Ba.

 8.3.8. Conversions Hexa-Decimal
	Pour la conversion d'un nombre hexa en un nombre decimal, on se sert
    de la proposition suivante: X*1=X. Vous me direz "ha, ‡a, on le savait.
    Mais o— cela nous mŠne-t-il?". Et bien, il se trouve que si le premier X
    est exprim‚ en hexa, et le deuxiŠme en decimal, la conversion est termin‚e.
    Il suffit donc de multiplier par 1 en mode SETDEC pour r‚aliser la conver-
    sion.
	B=0 A		%sommme partielle
	LC 00001	%facteur 1
        SETDEC          %passage en SETDEC (NDGQR: en decimal)
	*.Boucle
	  ?ABIT=0 0
	  GOYES .Im
		B=B+C A	%Addition en DECIMALE
	  *.Im
	  C=C+C A	%multiplication en DECIMALE
	  ASRB A	%division en HEXA (les d‚calages ne prennent pas en
			%compte SETDEC et SETHEX)
	?A#0 A
	GOYES .Boucle
        SETHEX          %et on oublie pas de retourner en mode SETHEX

    Pour la conversion decimale vers hexa, onr‚alise une lecture virtuelle
    d'un nombre decimale. Cela ce traduit ainsi
	A=0 A
	%retournement de Ca
	CPEX 4	%Echanges des quartets 0 et 4
	CPEX 0
	CPEX 4
	CPEX 1	%echanges des quartets 1 et 3
	CPEX 3
	CPEX 1
	*.Boucle
          B=A A      %A=A*10
	  A=A+A A
	  A=A+A A
	  A=A+B A
          B=0 A      %A=A+digit
	  B=C P
	  A=A+B A
          CSR A      %on passe au digit suivant
	?C#0 A
	GOYES .Boucle

 8.3.9. Division (principe et entiŠre)
	Le principe est le mˆme que celui de la multiplication, on va diminuer
     progressivement une valeur test qui correspondait … la valeur de chaque
     bit. mais voyons l'algo de A/B
	While B pair
	{
		A=A/2
		B=B/2
	}
	While A>B
	{
		B=B+B
	}
	C=0
	While B pair
	{
		C=C+C
		If A>B
		Then
		{
			A=A-B
			C=C+1
		}
		B=B/2
	}
    Ce qui donne en assembleur
	%A/C
        ?CBIT=1 0        %on regarde s'il faut diviser par 2
	GOYES .imp1
	*.Pa1
                ASRB A   %On fait les division par 2
		CSRB A
        ?CBIT=0 0        %et on teste s'il faut
        GOYES .Pa1       %recommencer
	*.Imp1
	C=C+C A		%je recommence par multiplier par 2 pour 				%pouvoir faire un DO et non un WHILE aprŠs.
	?A>=C A		%le while
	GOYES .Pg
	*.Mg
		C=C+C A	%multiplication par 2
	?C<A A
	GOYES .Mg
	*.Pg
        B=0 A           %resultat … 0
	*.Boucle
             B=B+B A    %Multiplication du resultat
             ?A<C A     %je peux soustraire?
             GOYES .Pas_moins
                 A=A-C A  %soustraction
                 B=B+1 P  %modification du resultat
             *.Pas_moins
             CSRB A       %et division du diviseur
	?CBIT=0 0
	GOYES .Boucle

 8.3.10. Autre op‚rations (racine entiŠre)
	Pour la racine entiŠre, on se sert du fait que la somme des N premiers
    nombres impairs est ‚gale … n^2. Il suffit donc pour avoir une approximation
    de cette racine d'un entier de lui enlever succesivement les n premiers
    nombres impaires obtenus tout simplement par 1+2+2+2+2+2+2...+2
	LC FFFFF	%C=-1
	*SQRT
	  C=C+2 A	%C=1,3,5...
	  A=A-C A	%s'il y a retenue, c'est que la somme des npremiers
			%nombres impairs etait superieure … A.
	GONC SQRT	%Donc SQRT(A)=C/2
	CSRB A	%et voila, c'est-y pas beau ‡a!
    De maniŠre g‚n‚rale, on obtient une suite convergente vers un fonction
    math‚matique quelconque grƒce la m‚thode de Newton. Qui dit que la suite
    X(n+1)=Xn-f'/f avec f la fonction quer l'on veut calculer (on veut
    calculer f(X)). Ce qui donne pour la racine carr‚e d'un r‚el:
	Xn+1=(Xn+2/Xn)/2
