-1

It does not generate the intended randomness.

I thought starting with a seed like $66 and xoring the two last lower bit and ror would give me the next random number and so on but it only shows $B3 and does not change at all.

How am I meant to feed? The line above random displays the number on portc as I want two numbers displayed after each other.

I am only using avr studio 4 for atmega 8535 at 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 
18
  • use code block (or intend by 4 spaces) for source code, add more info like what MCU, what exactly is wrong, ... is your code working on PC? if not try to trace it what is wrong ... and port to MCU asm when it is working. If you have breakpoint/trace capabilities on your MCU then you can skip the PC part. Right now your question is really just why is this code not working which is off-topic so voting to Close for now Commented Mar 27, 2015 at 7:26
  • it does not generate the intended randomness, i taught starting with a seed like $66 and xoring the two last lower bit and ror would give me the next random number and so on but it only shows $B3 and does not change at all any help would be appreciated by the way i am only using avr studio 4 for atmega 8535 at 1Mhz Commented Mar 27, 2015 at 7:31
  • you are feeding temp=$66 each random call so the result is always the same ... you should feed the temp only once. also I would add a swap of bits (not just ror) it usually leads for better randomness. also what are the 3 lines above random: label do ... they are not executed on call random !!! Commented Mar 27, 2015 at 7:36
  • i am a bit confuse on the seeding bit please could you please help explain how i am meant to feed without using temp. the line above random displays the number on portc as i want two numbers displayed after each other Commented Mar 27, 2015 at 7:39
  • execute ldi temp,$66 at program init and remove it from random subroutine. Also temp is a bad name for this ... when your program grows try to rename it to random_tmp for example Commented Mar 27, 2015 at 7:41

1 Answer 1

1

After some searching through ancient asm source code archives of mine I found this for x86 MSDOS NASM platform I was using back in the days:

;.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 

The idea is to have some stored number do some basic ALU operations like +,*,/,<<,>>,&,^ but ensure that no saturation occurs and usually swap of H,L of some value to keep the randomness in check. So port this to your asm but I strongly recommend to code it and try on PC first to see if the randomness is OK for your task.

BTW you can use also the program memory or any ROM content as base for randomness ... this is also exploiting the internal RTC block so you have to omit that part or add a timer or just loop through bunch of non empty data instead.

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

I found even older demo of mine called NoSignal (from 1997 in TASM) which have rnd inside:

 .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 

It fill screen and speaker with white noise as if no antenna cable in analog TV. This version is 44 Bytes long, pseudo random generator starts at label l0:

  • ax is the generated number (and also the prevvious generated number like you temp)
  • di is incrementing (something like actual time)...
  • cl is decrementing

so if I look at it right it should be enough:

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

and add push/pop store the registers/values if needed. If you need something more sophisticated then use modulo prime arithmetics.

[edit1] simple C++ pseudo random generator

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; } 

The above random generators was tighted to DOS environment time or special usage. This one is not ... the randomness is like this:

randomness graph

when I use it to fill NoSignal image window the result is this:

NoSignal

and here Gif animation:

NoSignal 320x240x3

The NoSignal fill code is as this:

 for (int y=0;y<ys;y++) for (int x=0;x<xs;x++) pyx[y][x]=0x00010101*int(rnd()>>8); 

So just high 8bit from the 16bit pseudo random number is used the multiplication just converts this 8bit number to gray-scale color.

  • xs,ys is image size
  • pyx is the direct image pointer to its lines

Do not change the seed numbers without proper testing with this on PC

Wrongly selected seeds leads to no randomness at all. If you want to safely seed (without testing) then seed with provided constants and then call rnd() as much times as the new seed number of yours is. Busted this right now so there may be better seeds for this, these are just the first ones I found that gives fairly good results

These seeds are also good:

 WORD rnd_d0=0x37A6; WORD rnd_d1=0x377A; WORD rnd_d2=0x3BC3; 
Sign up to request clarification or add additional context in comments.

3 Comments

@alex had a bit time for this so I tested mine old random generators and without MSDOS time or special way of usage there are not that good so i created something that is platform and usage independent see [edit1] it uses 16 bit ALU so if do not have any code some from 8bit ALU source is in C++ so there should not be any problems with porting to asm. If you need something better then specify the randomness properties you need
Rotate-through-carry (rcr/ rcl) with count > 1 is quite slow on modern x86: 8 uops on Intel Haswell for example, or 15 m-ops on AMD Steamroller. This is I guess optimized for code-size, not speed, and/or for much older CPUs. (even early P6 CPUs like PII had faster rcr).
@PeterCordes that was more like for AMD 80386 up to AMD K5... and yes it was optimized for code length

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.