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 modulo

Pseudo supprimé
Pseudo supprimé 01 novembre 2014 à 18:54:31

Yop,

en TP de C, j'ai été ammené à écrire un code qui faisait apparaître une situation dans laquelle j'ai choisi de faire une suite de divisions / additions pour obtenir le résultat. Le chargé de TP m'a dit que le plus rapide et logique aurait été de faire un modulo, je lui ai demandé en détail comment était implémenté le modulo pour qu'il soit plus rapide que la division entière et j'ai pas eu de réponse.
Je me rappelle pas avoir vu d'instruction modulo en assembleur.. donc j'ai cherché et effectivement ce que je trouve semble confirmer ce que je pensais.. du coup pour avoir le coeur net j'ai essayé le code suivant :

for(i=1;i<16;i++) {
a = 27 % i;
}

avec a, et i unsigned pour pas avoir de problème de signe dans les opérations asm résultantes et j'obtiens ça en sortie de gcc sans optimisation :

movl $27, %eax // eax = 27
movl $0, %edx // edx = 0
divl -4(%rbp) // divise (quoi ?) par i
movl %edx, -8(%rbp) // a = edx
addl $1, -4(%rbp) // i++

Donc il semblerait que le modulo soit simplement implémenté par une division entière.

Maintenant les questions : divl -4(%rbp) l'instruction a qu'une opérande.. qu'est-ce qui est divisé par celle-ci (enfin comment sont gérés les registres avec div) ? Pourquoi est-ce que edx est mis à 0 ? Finalement est-ce vrai que le modulo est plus rapide que le div et une soustraction ? je dirais oui étant donné que div est implémentée de telle manière que le reste soit stocké dans edx même si la différence est d'une opération (sub) et que ça joue rien du tout au final. :noel:

RedStarLinux
RedStarLinux
Niveau 6
01 novembre 2014 à 18:59:43

Pourquoi tu veux coder la fonction modulo en assembleur :question: Cette fonction est déjà présente en C. Et coder une fonction en assembleur plutôt qu'en C ne rendra pas ton programme plus rapide.

Pseudo supprimé
Pseudo supprimé 01 novembre 2014 à 19:02:11

Je veux pas coder le modulo en assembleur, je voulais savoir comment était implémenté le modulo du C en assembleur. :ok:

RedStarLinux
RedStarLinux
Niveau 6
01 novembre 2014 à 19:08:15

En DUT je me souviens avoir vu comment fonctionnait en assembleur toutes les opérations basiques mais je ne pense pas
avoir vu le modulo. Toute façon, pour cette fonction, le système a besoin de diviser deux nombres et après de récupérer le reste :oui:
Au lieu de t'embêter avec une boucle for, pourquoi tu ne calcules pas le modulo d'une seule valeur histoire d'avoir uniquement le code machine qui permet de calculer un modulo :ok:

Pseudo supprimé
Pseudo supprimé 01 novembre 2014 à 19:10:13

Parce que je l'ai dans le for :
movl $27, %eax // eax = 27
movl $0, %edx // edx = 0
divl -4(%rbp) // divise (quoi ?) par i
movl %edx, -8(%rbp) // a = edx

Et que sans for la variable est directement mise à la valeur du modulo sans faire le calcul explicitement.

RedStarLinux
RedStarLinux
Niveau 6
01 novembre 2014 à 19:13:37

Même avec le flash -O0 :doute:

RedStarLinux
RedStarLinux
Niveau 6
01 novembre 2014 à 19:13:53
  • flag :nah:
Pseudo supprimé
Pseudo supprimé 01 novembre 2014 à 19:15:09

Oui :noel: :

  1. include <stdlib.h>
  2. include <stdio.h>

int main(int argc, char **argv)
{
unsigned int a = 27 % 16;
return 0;
}

=>

main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl %edi, -20(%rbp)
movq %rsi, -32(%rbp)
movl $11, -4(%rbp)
movl -4(%rbp), %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Debian 4.7.2-5) 4.7.2"
.section .note.GNU-stack,"",@progbits

:d)

"movl $11, -4(%rbp)"

:noel:

RedStarLinux
RedStarLinux
Niveau 6
01 novembre 2014 à 19:16:32

Et si tu demandes à l'utilisateur de saisir une valeur :hap:

-MrPocolo
-MrPocolo
Niveau 10
01 novembre 2014 à 19:17:48

" divl -4(%rbp) l'instruction a qu'une opérande.. qu'est-ce qui est divisé par celle-ci (enfin comment sont gérés les registres avec div) ? "

" Pourquoi est-ce que edx est mis à 0 ? "

L'instruction div divise le dividende qui est contenu dans les registres EAX et EDX, la première partie de celui-ci (bits de poids faible) est contenue dans le registre EAX et la deuxième partie dans le registre EDX, le dividende peut donc tenir sur 8 octets, là en l’occurrence 27 tient sur moins de 4 octets donc le registre EDX doit être mit à 0.

Pseudo supprimé
Pseudo supprimé 01 novembre 2014 à 19:20:29

Redstar :d) pourquoi m'encombrer d'E/S :noel:

MrPocolo :d) Ah ok, donc div r ça fait (eax) | (edx << 32) / r :(

Pourquoi pas faire tout ça sur rax par exemple ? :(

RedStarLinux
RedStarLinux
Niveau 6
01 novembre 2014 à 19:24:08

Ou alors tu fais une boucle for qui va incrémenter un nombre jusqu'à un certain nombre et après tu calcules le modulo du nombre calculé au dessus avec un autre nombre :oui: Si tu as bien le flag -O0 le compilateur ne touchera pas à la boucle :oui:

Paulop
Paulop
Niveau 12
01 novembre 2014 à 19:40:50

J'imagine que c'est pas fait avec rax car c'est du x64, et de toute façon on va utiliser EDX pour y mettre le reste.

Paulop
Paulop
Niveau 12
01 novembre 2014 à 20:12:19

Par contre en x64 je comprend pas un truc :

a = (1<<31) % i;
00007FF65EA41491 xor edx,edx
00007FF65EA41493 mov rax,0FFFFFFFF80000000h
00007FF65EA4149A div rax,qword ptr [i]
00007FF65EA4149F mov rax,rdx
00007FF65EA414A2 mov qword ptr [rsp],rax

Pourquoi il xor edx et par rdx ?

Pseudo supprimé
Pseudo supprimé 01 novembre 2014 à 20:18:48

Bah d'après ce qui a été dit c'est les 32 bits de edx qui font les 32 bits forts du dividende, et edx c'est les 32 bits faibles de rdx donc div s'occupera pas des 32 bits forts de rdx. :(

Paulop
Paulop
Niveau 12
01 novembre 2014 à 20:38:59

Ben la il va utiliser rdx:rax mais il met que EDX a zero.

J'ai du louper un détail.

Pseudo supprimé
Pseudo supprimé 01 novembre 2014 à 20:47:32

div rax,qword ptr [i]

Pourquoi y a deux opérandes déjà ? :(

Et puis ici ils disent que rdx doit être à 0 :
https://www.cs.uaf.edu/20006/fall/cs301/support/x86_64/
" Bizarrely, on input rdx must be zero, or you get a SIGFPE."

Paulop
Paulop
Niveau 12
01 novembre 2014 à 20:50:19

C'est juste la notation de MSVC. (Visual Studio)

Pseudo supprimé
Pseudo supprimé 01 novembre 2014 à 20:52:48

Okay, dans le manuel d'intel il est écrit :

"In 64-bit mode, the instruction’s default operation size is 32 bits. Use of the REX.R prefix permits access to addi-
tional registers (R8-R15). Use of the REX.W prefix promotes operation to 64 bits. In 64-bit mode when REX.W is
applied, the instruction divides the unsigned value in RDX:RAX by the source operand and stores the quotient in
RAX, the remainder in RDX."

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