IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

x86 32-bits / 64-bits Assembleur Discussion :

[Débutant] Parcours de chaque pixel d'une fenêtre


Sujet :

x86 32-bits / 64-bits Assembleur

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    434
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 434
    Par défaut [Débutant] Parcours de chaque pixel d'une fenêtre
    Bonjour, voici le code C que j'essaye de reproduire en assembleur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    	for( DWORD n=0; n<H*W; n++ )
    	{
    		screenbits[n]&=0x00ffffff;                  //l'alpha a zero
    		screenbits[n] =ARGBTable[ screenbits[n] ];        //on récupère la correspondance
    	}
    Celui ci parcours chaque pixel d'une fenetre met l'alpha à zero puis modifie la couleur en récupérant la correspondance dans une table. Donc comme il y a 3 couleurs (R G B) la table fait 256*256*256 l'alpha n'ayant pas d'importance.

    Et voici le code assembleur qui ne fonctionne pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    	BYTE* src=(BYTE*)screenbits;
    	BYTE* tbl=(BYTE*)ARGBTable;
    	DWORD npix=H*W;
     
    	__asm                                                                                             
    	{
    		   mov ecx, npix			//un compteur pour savoir quand on s'arrete
    		   mov ebx, src                  //pointeur vers les pixels dans ebx (32bits: ARGB)
    		   label:     
    				mov al, 0
    				mov [ebx+3],al		//on met l'alpha a 0 jusque la le code fonctionne
    				mov eax, tbl		//on place eax en pointeur au début du tableau de correspondance
     
    				add eax, [ebx+0]	//avance le pointeur (ARGBTable[ screenbits[n] ];)
    				mov edx, [eax+0]	//on récupère la nouvelle valeur dans edx
    				mov [ebx+0], edx	//enfin on remplace le pixel par la nouvelle valeur
    				add ebx,4			//on avance le pointeur d'un pixel (4 octets) ca c'est bon
    				dec ecx				//on décrémente le compteur, ca c'est bon
    				jnz label			//si le compteur est positif ou nul on poursuit la copie
    	}
    Voila peut etre que c'est le "mov eax, tbl" qui pose probleme je ne sait pas ne conaissant pas trop l'assembleur.

    Merci

  2. #2
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Par défaut
    Bonjour,

    Citation Envoyé par supergrey Voir le message
    Bonjour, voici le code C que j'essaye de reproduire en assembleur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    	for( DWORD n=0; n<H*W; n++ )
    	{
    		screenbits[n]&=0x00ffffff;                  //l'alpha a zero
    		screenbits[n] =ARGBTable[ screenbits[n] ];        //on récupère la correspondance
    	}
    Je suis partis du principe que "screenbits" et "ARGBTable" sont des DWORD*:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    __asm{
    push esi                                ; preserve non volatile regs.
    push ebx
    mov ecx, screenbits
    mov edx, ARGBTable
    mov ebx, npix                           ; H * W
    xor eax,eax                             ; EAX = loop counter = n = 0
    @@LoopStart:
        mov byte ptr [eax*4+ecx+3], 0       ; no alpha
        mov esi, dword ptr[eax*4+ecx]       ; ESI = screenbits[n]
        mov esi, dword ptr[esi*4+edx]       ; ESI = ARGBTable [ esi ]
        mov dword ptr [eax*4+ecx], esi      ; screenbits[n] = esi
        inc eax                             ; n++
        cmp eax, ebx                        ; n < H*W ?
    jb @@LoopStart
    pop ebx                                 ; restore regs
    pop esi
    };
    N'hésites pas si tu as des questions.

  3. #3
    Membre très actif
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    434
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 434
    Par défaut
    Merci, ça fonctionne très bien.
    Au niveau des questions:
    -le @@ ça sert à quoi ? ça ne passe pas à la compilation...
    -pour l'utilisation de la pile je pense qu'il s'agit d'éviter de modifier des registres utilisés, mais pourquoi le faire pour ebx et pas pour eax, ecx et edx ?
    -au sujet du xor est-ce que ça a un intéret par rapport à un mov de 0 qui me semblerais plus compréhensible ?
    -les ptr si je comprend bien c'est une sorte de cast
    -au niveau optimisation est-ce qu'il ne vaut pas mieux augmenter le compteur de 4 que de faire des multiplications à chaque fois ? Meme si c'est ce qui m'a empécher de voir mon erreur qui était de ne pas multiplier la valeur du tableau par 4.

  4. #4
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Par défaut
    Hello,

    Citation Envoyé par supergrey Voir le message
    -le @@ ça sert à quoi ? ça ne passe pas à la compilation...
    Ah, zut! C'est une convention perso héritée d'un mécanisme de l'assembleur MASM ('@B' pour sauter vers l'arrière et '@F' pour sauter vers l'avant. Les deux peuvent pointer vers le label '@@:' [ Enfin ça n'est pas important.]).
    Ca me permet de mieux voir mes labels sur de grandes plages de code assembleur. C'est légal en assembleur 'pur' mais j'avais oublier que ça ne l'était pas en C/C++...

    -pour l'utilisation de la pile je pense qu'il s'agit d'éviter de modifier des registres utilisés, mais pourquoi le faire pour ebx et pas pour eax, ecx et edx ?
    Comme je ne savais pas où était situé ton code dans la fonction C, j'ai préféré sauvegarder les registres non volatiles au cas où. l'ABI x86 (Windows) précise que EBX, ESI, EDI et EBP doivent être sauvegardés entre différents appels (les autres sont considérés comme étant volatiles).

    -au sujet du xor est-ce que ça a un intéret par rapport à un mov de 0 qui me semblerais plus compréhensible ?
    xor reg, reg est:
    - Plus petit (au niveau de la taille de l'instruction) que "MOV reg, 0"
    - Plus rapide que "MOV reg, 0"

    C'est un des "trucs" super connus en assembleur x86.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    -les ptr si je comprend bien c'est une sorte de cast
    'ptr' indique "pointé par", mais c'est spécifique à l'assembleur Microsoft (j'aurais dû le préciser ). D'autres assembleur n'utilisent pas du tout ce 'ptr' et s'en passent complètement.

    -au niveau optimisation est-ce qu'il ne vaut pas mieux augmenter le compteur de 4 que de faire des multiplications à chaque fois ? Meme si c'est ce qui m'a empécher de voir mon erreur qui était de ne pas multiplier la valeur du tableau par 4.
    En fait les multiplications sont "built-in" à l'instruction. Je crois que ça ne coute rien au niveau perf. Mais effectivement, tu peux tout à fait supprimer les *4 et augmenter le compteur de 4 à chaque tour de boucle.

  5. #5
    Membre très actif
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    434
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 434
    Par défaut
    OK, 'est très clair, merci beaucoup, je me coucherai moins inculte.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 28/09/2010, 23h23
  2. Récupérer le code couleur de chaque pixel d'une image
    Par darkwall_37 dans le forum Débuter
    Réponses: 4
    Dernier message: 18/05/2010, 23h14
  3. [Débutant] moyenne de chaque pixel d'une image
    Par ghadatou dans le forum Images
    Réponses: 4
    Dernier message: 16/02/2009, 22h05
  4. Récupération des pixels d'une fenêtre cachée
    Par youhoucmoa dans le forum Windows
    Réponses: 13
    Dernier message: 25/11/2008, 10h40
  5. Déplacement d'une fenêtre[débutante]
    Par monia dans le forum MFC
    Réponses: 4
    Dernier message: 27/05/2004, 12h38

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo