PureBasic

Forums PureBasic
Nous sommes le Mer 19/Juin/2019 10:04

Heures au format UTC + 1 heure




Poster un nouveau sujet Répondre au sujet  [ 10 messages ] 
Auteur Message
 Sujet du message: Boucle For Next en asm
MessagePosté: Mar 03/Juil/2012 16:19 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 08/Juil/2007 18:32
Messages: 1307
Localisation: Toulouse
Bonjour,

Dans le cadre d’un développement 6502, pour la console portable Lynx, je souhaite transformer en langage d’assemblage une partie du code C composé de boucle for. Ces boucles sont en effet très gourmandes en ressource machine ! J'imagine que le fonctionnement 6502 et x86 est à peu près le même, avec possibilité de transfert de données dans les registres du CPU et adresse mémoire.

assembleur Lynx: RA65.exe et LYXASS.exe
et un LIBR65.EXE qui doit concerner les librairies.

Ci-dessous, un exemple basique de ma conception, en asm (dans la procédure Vtest():

Code:
uchar vac=0x00; // déclaration variable testable en assembleur
uchar vac=0x01; // si j'active cette ligne, la variable vac sera donc mis à 1, ce qui provoquera avec la commande BNE une boucle infini.

void Vtest()
{
#asm
rretour:
   clc ; mise à 0 de l'Accumulateur
   lda _vac ; charge le contenu de la variable vac dans l'Accumulateur du 6502
   bne rretour ; Si Accumulateur > 0 Alors goto rretour
#endasm
};

// et enfin l'appel de la procédure, donc à placer dans la boucle principale:
Vtest(); // si vac=0x01 alors le programme se bloque comme prévu (c’est juste pour tester voyez).


un autre exemple en asm avec plus de commandes:
Code:
// manual clear of collision buffer
void clear_coll_buffer(void) {
#asm
      pha
      phx
      phy
      lda #0
      ldy #10
loop0   ldx #0
loop1   sta $9C60,x
      dex
      bne loop1
      dey
      bne loop0
      ply
      plx
      pla
#endasm
}



******************** LDA STA

Et voici le code en C:
Code:
// ** LDA STA ******************************************
// ** Ci-dessous le code à transformer en asm 6502 ***
// *******************************************************

// Tout d'abord, voici la déclaration des variables:

int col_x, tile_x, grpx, lecx, comptx, compty, brnbr, level, tlnb;

uchar tbr01[7][56]=
{
   {0,0,0,0,0,23,24,25,26,27,0,0,0,0,0,0,0,0,0,23,24,25,26,27,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,7},
   {0,0,0,0,0,19,20,21,22,0,0,0,0,0,0,0,0,0,0,19,20,21,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,8},
   {0,0,0,0,0,15,16,17,18,0,0,0,0,15,0,0,0,0,0,0,16,17,18,0,0,0,1,7,28,28,28,1,7,0,0,0,0,0,0,0,1,7,0,0,0,0,0,0,0,0,0,0,0,0,2,8},
   {12,13,12,13,12,14,12,14,12,13,12,13,12,14,12,13,12,13,12,13,12,14,12,13,12,13,12,13,12,13,12,13,12,13,12,13,0,0,1,3,2,8,0,0,0,0,0,0,0,0,0,0,0,0,2,8},
   {10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,1,3,5,7,10,11,10,11,10,11,10,11,10,11,10,11,1,3,5,3,2,8,0,0,0,0,0,0,0,0,0,0,0,0,2,8},
   {1,3,5,7,9,9,9,9,9,9,1,3,5,3,5,3,5,3,5,7,2,4,6,8,7,9,9,9,9,9,9,1,3,5,3,5,3,5,5,5,2,8,0,0,0,0,0,0,0,0,0,0,0,0,2,8},
   {2,4,6,8,3,5,3,5,3,5,2,4,6,4,6,4,6,4,6,8,2,4,6,8,8,3,5,3,5,3,5,2,4,6,4,6,4,6,6,6,2,8,3,5,3,5,3,5,3,5,3,5,3,5,2,8}
};



// Ci-dessous, vous voyez le code en C que je souhaite tranformer en asm. Ce code est situé dans la boucle principale :

         col_x+=1;
         if (col_x>23)
            {
            col_x=0;tile_x+=1;
            
            for(grpx=0 ; grpx<6; grpx++) // de 0 à 5, ce qui fait 6 tests voyez.
               {
               for(lecx=(grpx*8) ; lecx<(grpx*8)+8; lecx++) // de 40 à 47, ce qui fait 8
                  {
                  if (tile_x == 2+lecx)
                     {
                     comptx = 8+lecx;brnbr = 7*(lecx-(grpx*8));
                     for(compty=0 ; compty<7; compty++) // de 0 à 6, ce qui fait 7
                        {
                        if (level==1)
                           {
                           tlnb=24;tlnb=tlnb+brnbr;
                           SCBDATA(&SCB[tlnb][0])  = dctab[tbr01[compty][comptx]%29];
                           SCBX(&SCB[tlnb][0]) = comptx*24;
                           SCBY(&SCB[tlnb][0]) = compty*24;
                           ++brnbr;
                           }
                        }
                     }
                  }
               }
               
            }
            
         col_x-=1;
         if (col_x<1)
            {
            col_x=24;tile_x-=1;
            
            for(grpx=0 ; grpx<6; grpx++) // de 0 à 5, ce qui fait 6
               {
               for(lecx=(grpx*8) ; lecx<(grpx*8)+8; lecx++) // de 40 à 47, ce qui fait 8
                  {
                  if (tile_x == 1+lecx)
                     {
                     comptx = lecx;brnbr = 7*(lecx-(grpx*8));
                     for(compty=0 ; compty<7; compty++) // de 0 à 6, ce qui fait 7
                        {
                        if (level==1)
                           {
                           tlnb=24;tlnb=tlnb+brnbr;
                           SCBDATA(&SCB[tlnb][0])  = dctab[tbr01[compty][comptx]%29];
                           SCBX(&SCB[tlnb][0]) = comptx*24;
                           SCBY(&SCB[tlnb][0]) = compty*24;
                           ++brnbr;
                           }
                        }
                     }
                  }
               }
               
            }


source mascot1 (scrolling + test sprite zoom) pour la console Lynx:
http://www.mirari.fr/gBdW

_________________
config de mon ordi: seven, directx11, Pentium(R) DualCore E5700, RadeonHD 4550 512MB, PureBasic 4.61 x86


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Boucle For Next en asm
MessagePosté: Ven 06/Juil/2012 8:50 
Hors ligne

Inscription: Mer 14/Sep/2011 16:59
Messages: 898
Les puces motorola 6xxx et les puces intel x86 ainsi que leur assembleurs sont très différents et un spécialiste du x86 ne pourra rien faire sur un 6502 et vice versa. Le jeu d'instruction, les registres, les bugs à connaitre (et oui les puces elle-même sont bogguées ! http://fr.wikipedia.org/wiki/MOS_Technology_6502), tout diffère d'une puce à une autre.

C'est vrai que l'assembleur 6502 a l'air simple et doit être assez rapide à apprendre mais t'aurais plus de chance de réponse en postant sur un forum spécialisé dans cette puce.

Pour info, il a été prouvé qu'un compilateur C était toujours plus performant qu'un humain même spécialisé dans l'assembleur. C'est dû au fait que le C est assez bas niveau et qu'à ses débuts tout les ingénieurs et chercheurs du monde se sont rués dessus pour le perfectionner. Mais bon, il est encore possible d'améliorer une boucle par-ci par-là.

Mesa.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Boucle For Next en asm
MessagePosté: Ven 06/Juil/2012 11:51 
Hors ligne
Avatar de l’utilisateur

Inscription: Jeu 07/Avr/2005 1:06
Messages: 1489
Localisation: Rennes
Salut

Attention :
Code:
clc ; mise à 0 de l'Accumulateur

Ne met pas à 0 l'accumulateur, c'est juste le carry qui est mis à 0
On utilise CLC avant de faire des additions, pour être sûr de ne pas rajouter la retenue
Le CLC est ici inutile :wink:


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Boucle For Next en asm
MessagePosté: Ven 06/Juil/2012 20:21 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 08/Juil/2007 18:32
Messages: 1307
Localisation: Toulouse
On m'a conseillé d'optimiser, en effectuant les calculs avant l'une des boucles par exemple:
Grpx×8 à chaque itération, c'est lourd, donc stocker dans une variable le résultat, puis utiliser cette variable dans la boucle, au lieu de refaire à chaque le calcul. C'est du bon sens, mais encore faut-il y penser. Une autre astuce consiste à remplacer la multiplication par 8 par <<3

Si vous avez un petit exemple de boucle en asm, même en x86, je suis toujours intéressé.
:mrgreen:

_________________
config de mon ordi: seven, directx11, Pentium(R) DualCore E5700, RadeonHD 4550 512MB, PureBasic 4.61 x86


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Boucle For Next en asm
MessagePosté: Lun 16/Juil/2012 9:57 
Hors ligne
Avatar de l’utilisateur

Inscription: Ven 11/Fév/2005 17:34
Messages: 4210
Localisation: Arras, France
Mesa a écrit:
Pour info, il a été prouvé qu'un compilateur C était toujours plus performant qu'un humain même spécialisé dans l'assembleur. C'est dû au fait que le C est assez bas niveau et qu'à ses débuts tout les ingénieurs et chercheurs du monde se sont rués dessus pour le perfectionner. Mais bon, il est encore possible d'améliorer une boucle par-ci par-là.


J'ai souvent lu des discussions là-dessus entre les afficionados du C et de l'assembleur. De fait, un compilateur est fait par des pros de l'assembleur ET du C. Le compilo sert pour des codes de grande taille, difficiles et longs à faire en assembleur. Le compilateur est fait par des armées de développeurs qui suivent et travaillent de concert avec les constructeurs (quand ils ne travaillent pas pour eux...).

Mais il ne faut quand même pas oublier plusieurs choses importantes pour nous, les humains : la passion, l'art, le rêve ! Ainsi, il y a quand même de supers bons programmeurs en assembleur (de même qu'il y en a en C...) qui te feront des codes magnifiques qu'aucun compilo ne saurait approcher. Pour plusieurs raisons :
  • le compilo ne connait pas la finalité du code, le plus souvent il ne fait que repérer des motifs qu'il remplace par des codes plus efficaces ; cela ne peut se faire sur l'ensemble d'un code qu'avec plusieurs passes, mais le nombre de passes est forcément limité...
  • la première des optims tient dans l'algo, et les limites des langages de haut niveau ne se retrouvent pas en assembleur. Ainsi, il existe des façons de faire des boucles en assembleur qui n'existent pas en C...
  • Le code modifié est souvent déconseillé, mais il permet de faire des choses bien sympa, comme des protections fortes ; difficile à faire en C.
  • Le code généré est difficile à faire si on ne connait pas l'assembleur... Et ça peut être bien utile !

Bref, il y aura encore longtemps des compétitions entre programmeurs/langages, et pourvu que ça dure ! Vive la diversité :)


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Boucle For Next en asm
MessagePosté: Lun 16/Juil/2012 14:49 
Hors ligne

Inscription: Mer 14/Sep/2011 16:59
Messages: 898
Je ne sais pas si peut aider mais voici une boucle en assembleur pour x86.
Les accumulateurs : AX=16 bits, EAX=32bits, RAX=64bits


Code:
PUSH EAX ; sauvegarde de l'accumulateur sur la pile au cas où un sous-programme en attente l'utilserait
PUSH ECX ; idem. CX était prévu pour faire des boucles, justement.

MOV ECX, 20 ; On met le compteur (nombre de boucle) à 20

boucle: ; étiquette sur laquelle on va boucler (peut s'écrire différemment suivant les assembleurs

; Mettre les instructions à faire

DEC ECX ; on décrémente ECX de 1 => ECX = ECX - 1

CMP ECX, 0 ; On compare ecx avec 0
JE exit ; jump if equal, si ecx = 0 alors on saute au label exit sinon on continue
JUMP boucle ; on saute vers boucle pour refaire une boucle si ecx <> 0

exit : ; fin de la boucle
POP ECX ; on récupère le ecx comme il était avent la boucle (attention à gérer la pile convenablement)
POP EAX ; idem

; instruction ici


;=================
; Souvent les programmeurs préfère mettre le test en premier, comme ici :
http://stackoverflow.com/questions/6805 ... -jmp-jcond

Il existe plusieurs variantes.
Les x86 ont une instruction spéciale qui simplifie tout :
JECXZ - jump if ECX is zero

On peut aussi comparer des octets directement en mémoire
CMPS[B/D/W] : Compare l'octet/le mot/le double-mot qui se trouve en DS:ESI avec celui qui se trouve en ES:EDI.

Mesa.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Boucle For Next en asm
MessagePosté: Mar 17/Juil/2012 10:38 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 08/Juil/2007 18:32
Messages: 1307
Localisation: Toulouse
Mesa a écrit:
Je ne sais pas si peut aider mais voici une boucle en assembleur pour x86.
Grand merci, c'est exactement ce type d'exemple qu'il me fallait. Je comprend la théorie de l'assembleur, c'est là le vrai langage. Et pouvoir insérer quelques lignes d'assembleur, c'est comme attraper le pom pom quand on était gosse sur un manège, c'est que du bonheur. :D


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Boucle For Next en asm
MessagePosté: Mar 17/Juil/2012 10:44 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 09/Oct/2005 16:51
Messages: 8670
J'ai une question peut-être bête mais je la pose tout de même...
On peut insérer de l'assembleur dans notre code PB. Mais si je ne m'abuse, lors de la compilation tout est converti (enfin compilé) en assembleur par PB. Donc quel est l'intérêt (hors celui de l'apprentissage) d'insérer de l'ASM dans un code ?

_________________
~~~~Règles du forum ~~~~
.: Ar-S :. Tour + portable W10 x64 PB 5.4x / 5.6x
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
RESIZER GOLD : Mon logiciel de redimensionnement par lot 100% PB


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Boucle For Next en asm
MessagePosté: Mar 17/Juil/2012 10:51 
Hors ligne
Avatar de l’utilisateur

Inscription: Ven 11/Fév/2005 17:34
Messages: 4210
Localisation: Arras, France
Plusieurs bonnes raisons :
  • L'asm directement concocté par tes soins peut être de meilleure qualité que celui généré par le compilateur de PB. Plus rapide, plus efficace, plus optimisé, plus joli, plus compact, etc.
  • Tu as récupéré un bout de code en assembleur quelque part et tu n'as pas envie de le convertir en PB.
  • Tu as besoin d'une instruction ASM particulière.
  • Tu codes toujours en ASM et tu n'utilises PB que pour des trucs en rapport avec l'API ou les fichiers. (c'est ce que je faisais en Blitz sur Amiga)
  • Tu veux être le seul à comprendre ton code !
etc.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Boucle For Next en asm
MessagePosté: Mar 17/Juil/2012 11:00 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 09/Oct/2005 16:51
Messages: 8670
En effet ça fait quelques bonnes raisons ;) merci.

_________________
~~~~Règles du forum ~~~~
.: Ar-S :. Tour + portable W10 x64 PB 5.4x / 5.6x
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
RESIZER GOLD : Mon logiciel de redimensionnement par lot 100% PB


Haut
 Profil  
Répondre en citant le message  
Afficher les messages postés depuis:  Trier par  
Poster un nouveau sujet Répondre au sujet  [ 10 messages ] 

Heures au format UTC + 1 heure


Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 1 invité


Vous ne pouvez pas poster de nouveaux sujets
Vous ne pouvez pas répondre aux sujets
Vous ne pouvez pas éditer vos messages
Vous ne pouvez pas supprimer vos messages

Rechercher:
Aller à:  

 


Powered by phpBB © 2008 phpBB Group | Traduction par: phpBB-fr.com
subSilver+ theme by Canver Software, sponsor Sanal Modifiye