Bonjour à tous !
Je suis à l'origine développeur C, mais suite à des besoins récent dans l'optimisation de traitement d'image, j'ai décidé de me mettre sérieusement à l'assembleur, afin de pouvoir utiliser les optimisations processeur spécifiques, et notamment le MMX (si vous en avez d'autre à proposer, je suis preneur).
Malheureusement mes connaissances en assembleur remontais à la fac, et n'était pas du tout orienté x86. Donc après plusieurs jours de documentation, je me suis enfin senti prêt à faire mes premiers essais. Et là, *paf*. J'utilise GCC qui utilise la norme AT&T, alors que toutes mes documentations était en norme Intel.... donc après une demi journée de plus pour comprendre les différences et l'intégration avec GCC, je m'y suis mis.
Pour m'entrainer, j'ai décidé de commencer doucement avec le MMX et de faire une fusion de deux images avec un niveau d'alpha.
Mais là, *repaf* après quelques essais très simple, j'obtient quelque chose qui ne ressemble pas du tout à ce que je souhaite. Voici mon début de code avec, en commentaire, ce que j'attendais dans les registres (sur archi 64bits):
Et voici le résultat de l'execution:
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
22 void test_mmx() { unsigned int color = 0x00000020; unsigned char data[8] = {255,255,255,255,255,255,255,255}; __asm__ ( "movl %%edx,%%eax\n\t" // eax = 0x00000020 "shl $16,%%eax\n\t" // eax = 0x00200000 "addl %%edx,%%eax\n\t" // eax = 0x00200020 "movd %%eax, %%mm0\n\t" // mm0 = 0x00000000 00200020 "movd %%eax, %%mm1\n\t" // mm1 = 0x00000000 00200020 "psllq $32,%%mm0\n\t" // mm0 = 0x00200020 00000000 "paddq %%mm1, %%mm0\n\t" // mm0 = 0x00200020 00200020 "movq %%mm0,(%%rdi)\n\t" // rdi = 0x00200020 00200020 : : "d"(color),"D"(data) ); printf("> %02x%02x%02x%02x %02x%02x%02x%02x\n",data[0],data[1],data[2],data[3],data[5],data[6],data[7],data[8]); }
Comme on le vois, le résultat n'est pas que j'escomptais dans le commentaire . Mais je n'arrive pas à comprendre où je me suis trompé. Ce doit être un truc tout bête, mais ça m'échappe.> 20002000 00200000
----
Question subsidiaire d'ultra débutant:
J'ai vu dans plusieurs documentation la syntaxe qui revient régulièrement:
Sauf que je n'arrive pas a trouver d'explication claire sur ce que calcul -0x20(%ebx, %ecx, 0x4). J'ai bien vu que c'était disp(base, index, scale).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 sub eax, [ebx + ecx * 4h - 20h] ; syntaxe Intel subl -0x20(%ebx, %ecx, 0x4), %eax ; syntaxe AT&T
En testant, -4(%ebx), je comprend bien qu'il me fait un offset d'adresse de -4. Mais pour les autres paramètres, le compilateur m'insulte dès que j'essai de mettre quelque chose. Par conséquent, je n'ai pas vraiment saisi comment ça s'utilise et dans quel cas.
J'ai pensé un moment que -1(%ebx, 4) allais me faire juste me faire un décalage de -1*4... Mais le compilateur n'en veut pas. Donc si quelqu'un peut m'éclairer là dessus, j'en resortirai un peu moins bête
Merci beaucoup pour votre aide !
Partager