CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

[ASM] mul vs imul?

drakenlorde
drakenlorde
Niveau 9
09 décembre 2015 à 02:01:46

Si mul est une multiplication pour nombre non signé et imul pour nombre signé, pourquoi si je fait
movq $4,%rax
movq $-5,%rbx
mulq %rbx
et que j'affiche le résultat avec printf, j'obtiens bien un nombre négatif malgré que j'utilise la version non signé?

Message édité le 09 décembre 2015 à 02:03:18 par drakenlorde
godrik
godrik
Niveau 30
09 décembre 2015 à 06:41:40

parceque tu fais le printf pour un type signe ? %d pour un entier signe %ud pour un entier non-signe.

Sinon la difference entre mul et imul est que mul te force a utiliser ax, al ou eax alors que imul supporte des registres, ou des immediates.

drakenlorde
drakenlorde
Niveau 9
09 décembre 2015 à 18:06:10

Oui j'utilise le printf pour type signé et pourtant le résultat est correcte malgré le mul non-signé , mais pourquoi la documentation dit que mul est signé et imul non signé si le résultat mémoire est exactement le même?
Merci

godrik
godrik
Niveau 30
09 décembre 2015 à 19:32:28

parceque la representation binaire est la meme. Tu peux aussi afficher un entier comme un float si ca t'amuse et tu auras le "mauvais" resultat.

drakenlorde
drakenlorde
Niveau 9
09 décembre 2015 à 22:49:17

Si la représentation binaire est la même, pourquoi la documentation prétend que mul est non signé et imul signé?

-MrPocolo
-MrPocolo
Niveau 10
10 décembre 2015 à 00:37:59

En fait avec les instructions de multiplication le produit complet est stocké dans deux registres, dans ton cas les 8 octets de poids faible sont stockés dans RAX et les 8 octets de poids fort dans RDX. Si tu fais mulq %rbx (multiplication non signée donc) avec -5 dans RBX alors l'assembleur prend ça pour un nombre positif et donc en vrai tu multiplies l'équivalent en non signé de -5 (18446744073709551611 en 64 bits, si je ne me trompe pas) par 4 mais tu ne le remarques pas car tu ne regardes que le contenu du registre RAX, en revanche si tu mets bout à bout les bits de RDX et RAX tu devrais trouver le résultat de cette opération et non pas -20.

Avec imul la représentation binaire sera effectivement la même sur les bits de poids faible (registre RAX) mais si tu regardes dans RDX ça sera différent, il y a une extension de signe qui est faite et pour 4 * -5 tu ne devrais trouver que des bits à 1 dans le registre RDX et en mettant bout à bout RDX et RAX ça devrait bien faire -20.

drakenlorde
drakenlorde
Niveau 9
10 décembre 2015 à 01:48:22

Observation très intéressante. Par contre je ne vois pas pourquoi le fait de mettre bout à bout rdx et rax devrait différencier de seulement rax dans un cas ou la valeur est suffisament petite pour être stocké seulement dans rax puisque, comme tu a dit, le reste des bits serons tous des 1 et n'aurons aucun effet sur notre valeur.

J'ai testé avec une multiplication 32 bit pour avoir un résultat final 64 bit edx:eax (ainsi affichable par printf), en fesant encore 4 * -5 avec l'instruction mul, et j'obtiens -20 en affichant seulement eax et -20 en mettant edx et eax bout à bout.

Le concept de signé/non signé ne fait de sens que lors de la lecture de bits. Si on lit non signé, on voit des nombre positif, si on lit signé, on voit négatif ou positif, mais ça n'existe pas lorsqu'on parle de la représentation binaire alors je ne comprend pas pourquoi la documentation décrit les instructions MUL/IMUL comme signé/non signé.

-MrPocolo
-MrPocolo
Niveau 10
10 décembre 2015 à 04:07:43

en fesant encore 4 * -5 avec l'instruction mul, et j'obtiens -20 en affichant seulement eax et -20 en mettant edx et eax bout à bout.

C'est pas avec imul plutôt? car avec imul ça serait normal mais avec mul en faisant 4*-5 tu devrais obtenir le résultat de 4 * 4294967291, ce qui donne 4294967276 dans EAX (ou -20 si tu interprète ça en signé sur 32 bits) et 3 dans le registre EDX, ce qui donne bien 17179869164 pour EDX:EAX. En tout cas moi j'obtiens ça, je viens d'essayer.

drakenlorde
drakenlorde
Niveau 9
10 décembre 2015 à 17:17:09

Ah je vois. Donc si on récupère seulement eax dans un résultat edx:eax, alors mul fonctionne pour nombre signé, mais pas lorsqu'on doit récupérer la valeur complète edx:eax.

-MrPocolo
-MrPocolo
Niveau 10
10 décembre 2015 à 18:51:46

Oui en fait mul fait une multiplication non signée et imul une multiplication signée mais cela ne se voit que si tu récupères la totalité du produit sur RDX:RAX ou sur EDX:EAX, alors que si tu utilises seulement le registre contenant les octets de poids faible mul et imul te donneront toujours le même résultat, ça donne donc l'impression que les deux instructions effectuent exactement la même opération même si ce n'est pas vraiment le cas.

Autrement l'autre particularité d'imul par rapport à mul, comme l'a dit godrik, c'est que imul peut aussi être utilisé avec deux ou trois opérandes au lieu d'une seule. A noter que si tu utilises les formes à deux ou trois opérandes le produit de la multiplication est toujours stocké dans un seul registre (l'opérande de destination) et il y a troncation du résultat si nécessaire, s'il y a eu troncation les flags d'overflow et de carry (OF et CF) du processeur sont mis à 1.
Pour la forme avec une seule opérande, aussi bien pour mul que imul, les flags OF et CF sont mis à 1 si le résultat ne tient pas entièrement sur le registre de poids faible, autrement dit ça t'indique si RDX ou EDX sont à 0 ou non.

Sous forums
  • Aide à l'achat Mac
  • Création de Jeux
  • Linux
  • Programmation
  • Création de sites web
  • Internet
  • Steam Deck
  • Macintosh
  • Hardware
La vidéo du moment