Comment donner un nombre aleatoire en asm ?
Modérateurs : Papy.G, fneck, Carl
- rendomizer
- Messages : 413
- Inscription : 17 juin 2016 21:00
- Contact :
Comment donner un nombre aleatoire en asm ?
Et oui je me demande bien comment on fait pour obtenir un nombre aléatoire en asm...
Je ne suis qu'un utilisateur pas un pro
Re: Comment donner un nombre aleatoire en asm ?
Bonsoir,
Sur un Z80, il n'y a pas de moyen simple pour obtenir un nombre aléatoire. La seule instruction qui te donne une valeur numérique qui varie est le registre R, mais son comportement est logique et prévisible (valeur croissante sur 7 bits en fonction du nombre de NOP pris par les instructions exécutées avant de lire le contenu du registre.
Dans un soft que j'avais fait il y a déjà longtemps, Colors Lines, j'avais couplé l'usage de ce registre avec un compteur qui augmente et s'arrête en fonction d'une action de l'utilisateur (appui sur une touche par exemple). Le résultat était ensuite mixé avec une table fixe de valeurs tirées "au hasard" une fois pour toute. C'était pas parfait mais mieux que rien .
Sur un Z80, il n'y a pas de moyen simple pour obtenir un nombre aléatoire. La seule instruction qui te donne une valeur numérique qui varie est le registre R, mais son comportement est logique et prévisible (valeur croissante sur 7 bits en fonction du nombre de NOP pris par les instructions exécutées avant de lire le contenu du registre.
Dans un soft que j'avais fait il y a déjà longtemps, Colors Lines, j'avais couplé l'usage de ce registre avec un compteur qui augmente et s'arrête en fonction d'une action de l'utilisateur (appui sur une touche par exemple). Le résultat était ensuite mixé avec une table fixe de valeurs tirées "au hasard" une fois pour toute. C'était pas parfait mais mieux que rien .
- rendomizer
- Messages : 413
- Inscription : 17 juin 2016 21:00
- Contact :
Re: Comment donner un nombre aleatoire en asm ?
Merci pour cette réponse. Je pensais qu'il y avait une astuce autre qu'une simple routine de balayage de la mémoire vive ou du registre R J'ai pensé a ton idée d'une action sur une touche et un compteur ! je pense que c'est une bonne idée finalement.
Je ne suis qu'un utilisateur pas un pro
-
- Messages : 7986
- Inscription : 18 sept. 2010 12:08
- Localisation : Brest et parfois les Flandres
Re: Comment donner un nombre aleatoire en asm ?
Traditionnellement dans la plupart des langages (BASIC, C, FORTH, PASCAL), on utilise un générateur pseudo-aléatoire congruentiel linéaire, mais les résultats sont plutôt peu aléatoires. En effet, il apparait des motifs réguliers quand on remplie une grille 2d (cf le calcul de PI par Dominique), preuve d'une très forte correlations entre les valeurs successives.
En plus cet algo utilisant une multiplication 16 bits est plutôt lent sur les cpu 8 bits.
Il existe des générateurs à base de décalages et xor logiques bien plus rapides et un peu plus aléatoires (en particulier parce que la graine/état interne est sur plus de 16 bits): https://en.wikipedia.org/wiki/Xorshift. Ceux la sont très bons et très efficaces sur les micros 8bits, par exemple sur Z80.
Cependant comme sur 6809 la multiplication 8bitsx8bits->16bits est très rapide, j'ai un code rikiki qui sort des nombres pseudo-aléatoire de bonne facture (période de 31870):Malgrès l'utilisation d'une multiplication ca n'est pas un générateur linéaire congruentiel, mais un générateur adapté pour 8bits inspirés des générateurs "multiply with carry" qui ont de meilleurs propriétés aléatoires que les générateurs linéaires congruentiels. On retrouve une version Z80 de ce genre de générateur en bas de: http://chuntey.arjunnair.in/?cat=4
Après il faut tirer une certaines quantité variable de nombres aléatoires si on ne veut pas sans arret ressortir indéfiniment la même série de nombre à chaque fois qu'on lance le programme. Pour cela il faut une source d'entropie (nom savant pour parler de bruit aléatoire). Sur les micros 8 bits elles sont rares. Les compteurs VIDEO peuvent le faire, mais le mieux est de faire une boucle d'attente tout en demandant à l'utilisateur d'appuyer sur une touche. On profitte de cette boucle pour tirer un nouveau nb aléatoire pour rien à chaque tour. Mais comme le nb de tours dépend de la vitesse de réaction de l'utilisateur (chose très variable), cela pré-initialise les générateurs avec une graine suffisamment aléatoire en pratique.
En plus cet algo utilisant une multiplication 16 bits est plutôt lent sur les cpu 8 bits.
Il existe des générateurs à base de décalages et xor logiques bien plus rapides et un peu plus aléatoires (en particulier parce que la graine/état interne est sur plus de 16 bits): https://en.wikipedia.org/wiki/Xorshift. Ceux la sont très bons et très efficaces sur les micros 8bits, par exemple sur Z80.
Cependant comme sur 6809 la multiplication 8bitsx8bits->16bits est très rapide, j'ai un code rikiki qui sort des nombres pseudo-aléatoire de bonne facture (période de 31870):
Code : Tout sélectionner
rnd ldd #3*256+249 ; graine (ne pas changer, celle là produit une longue période)
mul ; D=A*B 8x8->16 bits. Ultra rapide sur 6809 (11 cycles)
rnd1 addd #0 ;
sta <rnd1+2
stb <rnd+1+2
rts ; Reg A écrasé. Resultat dans le reg B de 0 à 255
Après il faut tirer une certaines quantité variable de nombres aléatoires si on ne veut pas sans arret ressortir indéfiniment la même série de nombre à chaque fois qu'on lance le programme. Pour cela il faut une source d'entropie (nom savant pour parler de bruit aléatoire). Sur les micros 8 bits elles sont rares. Les compteurs VIDEO peuvent le faire, mais le mieux est de faire une boucle d'attente tout en demandant à l'utilisateur d'appuyer sur une touche. On profitte de cette boucle pour tirer un nouveau nb aléatoire pour rien à chaque tour. Mais comme le nb de tours dépend de la vitesse de réaction de l'utilisateur (chose très variable), cela pré-initialise les générateurs avec une graine suffisamment aléatoire en pratique.
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos