Cómo sembrar para generar números aleatorios?

No genera la aleatoriedad deseada.

Pensé comenzar con una semilla como $ 66 y anotar los dos últimos bits más bajos y ror me daría el siguiente número aleatorio, y así sucesivamente, pero solo muestra $ B3 y no cambia en absoluto.

¿Cómo debo alimentarme? La línea superior aleatoria muestra el número en el puerto ya que quiero que se muestren dos números uno detrás del otro.

Solo estoy usando avr studio 4 para atmega 8535 a 1Mhz.

> ;Program to random numbers on port C > > ;Stack and Stack Pointer Addresses .equ SPH =$3E > ;High Byte Stack Pointer Address .equ SPL =$3D > ;Low Byte Stack Pointer Address > > .equ RAMEND =$25F ;Stack Address > > ;Port Addresses > > .equ PORTC =$15 ;Port C Output Address > > .equ DDRC =$14 ;Port C Data Direction Register > Address > > .equ numberoneddr=DDRC > > .equ numberoneport=portc > > .equ numbertwoddr=DDRC > > .equ numbertwoport=portc > > .equ delayCount=21 > > .equ random1 =$66 > > ;Register Definitions > > .def numberone =r1 ;Register to store data pointed > to by Z > > .def numbertwo =r2 > > .def temp =r16 ;Temporary storage register > > > > reset: > > ; initialize stack pointer. Done automatically at reset on many AVRs > > ldi temp, low (RAMEND) > > out spl, temp > > ldi temp, high (RAMEND) > > out sph, temp > > > > > ;port initialisation > > ldi temp,$FF > > out numberoneddr,temp > > out numberoneport,temp > > out numbertwoddr,temp > > out numbertwoport,temp > > > > ;Program Initialisation > > ldi temp,$66 > > rcall random > > mov numberone, temp > > out numberoneport,numberone > > rcall random > > mov numbertwo, temp > > out numberoneport,numbertwo > > > > > random: mov r19,temp > > ldi r17, 0x01 > > eor r19,r17 > > ror r19 > > mov temp,r19 > > ret > > > > delay: > clr r20 > > clr r21 > > ldi r22, delayCount > > loopDelay: > > dec r20 > > brne loopDelay > > dec r21 > > brne loopDelay > > dec r22 > > brne loopDelay > > ret 

Después de buscar un poco a través de antiguos archivos de código fuente asm, encontré esto para la plataforma x86 MSDOS NASM que estaba usando en los días anteriores:

 ;.rnd ;al=rnd num <0,ah>; .rnd: pusha mov cx,ax .rnd0: mov bx,[cs:.rnddat] mov ax,[cs:.rndtim] xor al,bh add ah,bh rcr ax,3 xor al,bl rcl ax,2 .rnd2: cmp al,ch jbe .rnde sub al,ch or ch,ch jnz .rnd2 sub al,al .rnde: mov ah,bl mov [cs:.rnddat],ax or al,1 xor ax,[fs:046Ch] add [cs:.rndtim],ax popa mov al,[cs:.rnddat] ret .rnddat:db 0,0 .rndtim:dw 0 

La idea es tener un número almacenado para realizar algunas operaciones básicas de ALU como +,*,/,<<,>>,&,^ pero asegúrese de que no ocurra saturación y, por lo general, intercambie H,L de algún valor para mantener la aleatoriedad en comprobar. Así que transfiéralo a tu ASM pero te recomiendo que lo codifiques y pruebes en la PC primero para ver si la aleatoriedad es adecuada para tu tarea.

Por cierto, puede usar también la memoria de progtwig o cualquier contenido de ROM como base para la aleatoriedad … esto también explota el bloque de RTC interno, por lo que debe omitir esa parte o agregar un temporizador o simplemente realizar un bucle de datos no vacíos.

 [0000:046C] are 4 Bytes master clock count (long integer) 0 = midnight and increments until a 24 hour equiv. 

Encontré una demo más antigua llamada NoSignal (desde 1997 en TASM) que se encuentra dentro:

  .386P IDEAL MODEL TINY CODESEG STARTUPCODE main: mov ax,19 ;320*200*256 int 16 push 0A000h ;Video segment pop es ;keyboard test,speaker delay v si=256 l0: ror ax,cl ;rnd...ax add ax,di stosw ;plot... loop r1 ;speaker delay... mov cx,si out 61h,al r1: or di,di jnz l0 push ax mov ah,1 ;test keyboard int 16h pop ax jz l0 ende: sub ax,ax ;turn off speaker and exit out 61h,al int 16h mov ax,3 int 16 ret END 

Llena la pantalla y el altavoz con ruido blanco como si no hubiera un cable de antena en la TV analógica. Esta versión tiene 44 bytes, el generador pseudoaleatorio comienza en la etiqueta l0:

  • ax es el número generado (y también el número generado anteriormente como tu temperatura)
  • di está incrementando (algo así como el tiempo real) …
  • cl está disminuyendo

entonces, si lo veo bien, debería ser suficiente:

  rnd:ror ax,cl ;rnd...ax add ax,di inc di dec cl ret 

y agregue push/pop almacenar los registros / valores si es necesario. Si necesita algo más sofisticado, utilice aritmética de módulo superior.

[edit1] simple generador pseudo aleatorio de C ++

 WORD rnd_d0=0x66; // these are seed numbers if not selected right then the randomness is not good WORD rnd_d1=0x5A; // these give fairly good results WORD rnd_d2=0xC3; WORD rnd() { rnd_d0^=rnd_d1|rnd_d2; // xor rnd_d1*=rnd_d2; // mul rnd_d2+=rnd_d1; // add rnd_d0=(rnd_d0<<8)|(rnd_d0>>8); // 8bit halves swap return rnd_d0; } 

Los generadores aleatorios anteriores se ajustaron al tiempo de entorno de DOS o al uso especial. Este no es … el azar es así:

gráfico de aleatoriedad

cuando lo uso para llenar la ventana de la imagen de NoSignal el resultado es este:

Sin señal

y aquí la animación Gif :

NoSignal 320x240x3

El código de relleno de NoSignal es el siguiente:

  for (int y=0;y>8); 

Así que solo se utiliza 8 16bit altos del número pseudoaleatorio de 16bit la multiplicación simplemente convierte este número de 8 8bit en un color de escala de grises.

  • xs,ys es el tamaño de la imagen
  • pyx es el puntero de imagen directo a sus líneas

No cambie los números de semilla sin una prueba adecuada con esto en la PC

Semillas mal seleccionadas no llevan a ninguna aleatoriedad. Si quieres sembrar de forma segura (sin pruebas), siembra con las constantes proporcionadas y luego llama a rnd() tantas veces como sea el número de semilla nuevo tuyo. Se rompió esto ahora, así que puede haber mejores semillas para esto, estos son solo los primeros que encontré que dan resultados bastante buenos

Estas semillas también son buenas:

  WORD rnd_d0=0x37A6; WORD rnd_d1=0x377A; WORD rnd_d2=0x3BC3;