La Division et le modulo en utilisant un seul divl instruction (i386, amd64)
J'essayais de venir avec inline assemblée pour gcc pour obtenir à la fois la division et le modulo en utilisant un seul divl
instruction. Malheureusement, je ne suis pas bon à l'assemblée. Quelqu'un pourrait-il svp m'aider sur ce point? Merci.
Voir stackoverflow.com/questions/3323445/... où j'ai utilisé cela comme un exemple de MSVC inline asm vs GNU C asm inline. (Y compris un travail
Voir aussi stackoverflow.com/questions/32741032/... pour un doublon, montrer que vous n'avez pas besoin d'utiliser asm inline (le compilateur le fait pour vous), mais aussi à montrer comment le faire correctement en ligne de l'asm. (Pas de différence significative pour DOSBoot réponse)
divl
wrapper fonction inline, avec une seule instruction à l'intérieur de l'asm inline déclaration, le même que D0SBoots la bonne réponse ici.)Voir aussi stackoverflow.com/questions/32741032/... pour un doublon, montrer que vous n'avez pas besoin d'utiliser asm inline (le compilateur le fait pour vous), mais aussi à montrer comment le faire correctement en ligne de l'asm. (Pas de différence significative pour DOSBoot réponse)
OriginalL'auteur | 2011-04-09
Vous devez vous connecter pour publier un commentaire.
Oui -- un divl produira le quotient dans eax et le reste dans edx. À l'aide d'Intel syntaxe, par exemple:
gcc
n'a même pas essayer d'optimiser les deux de ces opérations en un seul. Je vais vous acheter une bière si vous pouviez me donner gcc assemblée, de sorte que je peux l'utiliser comme fonction en ligne ou quelque chose...Fausse alarme. Désolé. CCAG-t-il pour moi si je n'oublie pas d'indiquer les drapeaux.
Cette réponse est assez hors sujet, car la question est spécifique à la GCC et de vous répondre avec de l'assemblée Intel syntaxe Charles et raylu sont tout autour de mieux.
il a demandé a une séquence d'instructions de montage qui permettrait de produire à la fois le quotient et le reste à l'aide d'une seule instruction div. Aucun de ces "réponses" des tentatives de le leur fournir. Ils sont tous les deux vraiment de commentaires, pas de réponses. La seule autre réponse réelle ici est DOSBoots'.
Non ce n'est pas ce qu'il demande, lisez la question: "j'ai essayé de venir avec inline assemblée pour gcc pour obtenir à la fois la division et le modulo en utilisant un seul
divl
de l'instruction".OriginalL'auteur Jerry Coffin
Vous êtes à la recherche de quelque chose comme ceci:
Bien que je suis d'accord avec les autres commentateurs qui, généralement, GCC fera pour vous et vous devez éviter l'assembly en ligne lorsque cela est possible, parfois, vous avez besoin de cette construction.
Par exemple, si le mot est inférieur au module, alors il est sûr d'effectuer la division de ce genre. Cependant, GCC n'est pas assez intelligent pour s'en rendre compte, parce que dans le cas général de la division d'une 64 bits d'un nombre par un nombre 32 bits peut conduire à débordement, et il en appelle à une routine de bibliothèque pour faire du travail supplémentaire. (Remplacer avec 128 bits/64 bits pour 64 bits Isa.)
"g"
pour la source et l'opérande n'est pas correct, parce que la DIV ne prend pas en charge immédiate des opérandes. Utilisation"rm"
. (En fait, vous pourriez vouloir"g"
de sorte que votre code va casser au moment de la compilation si vous êtes jamais tirer une balle dans le pied en forçant l'utilisation de DIV lorsque le diviseur est une constante de compilation.) Vous pourriez peut-être également utiliser__builtin_constant_p
pour détecter au moment de la compilation-constant opérandes. Cela devrait bien fonctionner avec gcc, mais clang évalue avant la fonction inline (de sorte que vous obtenez de faux négatifs).OriginalL'auteur D0SBoots
Vous ne devriez pas essayer d'optimiser vous-même. GCC fait déjà cela.
De course
rendements
Avis que le reste, %edx, n'est pas déplacé, car il est aussi le troisième argument passé à printf.
EDIT: La version 32 bits est moins déroutant. En passant -m32 rendements
Je suis sur gcc (Debian 4.5.2-4) 4.5.2, mais même 4.3. Êtes-vous en passant -O?
Je suis à l'aide de gcc 4.6.. mais putain! J'ai passé 30 minutes à jouer avec cette avant de demander ici et il s'avère que j'ai juste oublié de préciser "- O3'. J'avais "- mtune=native", mais il n'a pas aidé. Merci! Je devrais dormir un peu...
Pourquoi seulement
-O
? Utiliser au moins-O2
donc gcc sera judas le signe-extension dansedx
aveccdq
(akacltd
AT&T de la syntaxe, de l'IIRC). De toute façon, si vous écrivez une fonction qui prend deux arguments, et stocke les résultats à globals (ou les retourner comme une structure, ou de retourner un magasin de l'autre), il permettra d'éviter l'optimisation de loin, mais ont besoin de moins d'instructions que si vous écrivez unmain()
et l'utilisationvolatile
. Voir stackoverflow.com/questions/32741032/...pour montrer que le minimum nécessaire pour obtenir le comportement décrit dans la question.
OriginalL'auteur raylu
Heureusement, vous n'avez pas à recourir à l'assembly en ligne pour atteindre cet objectif. gcc fera automatiquement quand il peut.
$ cat divmod.c
$ gcc -O3 -std=c99 -Wall -Wextra -pedantic -S divmod.c -o -
OriginalL'auteur CB Bailey