>I am currently writing some arm programs, but I don't know how to do RND() in ARM code... I have to keep returning to the BASIC and doing !rnd=RND(100) and in armcode LDR r0,rnd which is VERY slow though.
>Can anyone send some armcode for making random numbers or some similar solution. Thanks.
This can be done in one instruction:
MLA r0,r0,r1,r2
If you set r1 to some large prime and r2 arbitrary, eg. 129
r0 will have a new value wich is pseudo-random, in the
range (0 to 2^32-1). The problem is to get it in the 0 to 100
range.
--
Michel Grimminck, Computational Physics, University of Amsterdam
http://www.fwi.uva.nl/~grimmink
>I am currently writing some arm programs, but I don't know how to do
>RND() in ARM code... I have to keep returning to the BASIC and doing
>!rnd=RND(100) and in armcode LDR r0,rnd which is VERY slow though.
>Can anyone send some armcode for making random numbers or some
>similar solution. Thanks.
Here is one that was posted some years ago (in another newsgroup)
1. Get your actual seed (32 bit).
2. shift left seed
3a. If the result is 0, or if the most significant bit
of the original seed was 1 (the one which got shifted out)
then perform an exclusive or with $1D872B41.
3b. Otherwise do nothing else.
4. The resulting value is your new seed. Go to 1.
In ARM this would be something like
\ seed in Rseed
\ 0x1D872B41 in Rval
ADDS Rseed, Rseed,Rseed \ alternatively use ASL
EOREQS Rseed,Rseed,Rval
EORCSS Rseed,Rseed,Rval
Note that not both of the conditional EORs can be executed, as the
first would clear the carry flag. This code assumes seed and constant
in registers. If you have these in memory do the appropriate
load/store operations before and after.
Torben Mogensen (tor...@diku.dk)
> I am currently writing some arm programs, but I don't know how to do
RND() in ARM code... I have to keep returning to the BASIC and doing
!rnd=RND(100) and in armcode LDR r0,rnd which is VERY slow though.
>
> Can anyone send some armcode for making random numbers or some similar
solution. Thanks.
So long as you only need one random number the standard way is just to
read the last three digits of the monotonic clock. Of course if you want
more than one there is the very real danger that a constant number of
cycles will have elapsed between clock calls, and so each 'random' number
will be a fixed distance apart.
What to do then is to generate pseudorandom numbers from these, by pushing
them through some nonlinear function, perhaps with parameters generated
from the last random number. The design of this function is critical for
both execution speed and for closeness to randomness.
I heard recently that a group of postgraduates at Bristol university had
succeeded in designing a card for a PC that could generate true random
numbers - I think this indicates the level of complexity in what seems a
really trivial problem.
UNfortunately I don't have any code for it tho'. ;-)
good luck,
Al
--
=====================================================================
Alan Donovan | /\_/\ All deadlines met.
Pembroke College | ( o.o ) All lectures attended.
Cambridge, England | ) ( All practicals completed.
aad...@hermes.cam.ac.uk | ( )__/ All pigs fed & ready to fly.
This is what I use for 'random' numbers in games.
LDR RO,seed
ADD R0,R0,#137
EOR R0,R0,R0,ROR #13
STR R0,seed
It's not random as such, but at least it's short.
Andy S.
> I am currently writing some arm programs, but I don't know how to do RND() in
> ARM code... I have to keep returning to the BASIC and doing !rnd=RND(100) and
> in armcode LDR r0,rnd which is VERY slow though.
.seed EQUD 123
.multiplier EQUD 1664525
ADR R2,seed
LDMIA R2,{R0,R1} ;load seed and multiplier together
MLA R2,R0,R1,R1
MLA R0,R2,R1,R1
STR R0,seed
EOR R0,R0,R2,ROR #16 ;32 bit random number in r0
Here is a very fine random number generator. It uses a linear congruential
algorthim with parameters suggested by Knuth in his seminal work, "The art of
Computer programming".
This routine actually calculates two random numbers and EORs them shifted
together. This is because the lowest bits of the random number generator are
not very random (this is because of the use of 2^32 as a modulus).
If you don't mind 24 bit random numbers (and ignore the bottom 8 bits) then
you can remove one of the MLAs and the EOR, thus
.seed EQUD 123
.multiplier EQUD 1664525
ADR R2,seed
LDMIA R2,{R0,R1} ;load seed and multiplier together
MLA R2,R0,R1,R1
STR R2,seed ;24 bit random number in r2
If you were generating a lot of these then you could reduce the entire random
number generation down to a single MLA, using two registers for the seed and
the multiplier.
Note: speed on the MUL/MLA instruction depends on the highest bit set in the
3rd argument. This ought to be made into the multiplier and not the seed if
possible. The MLA above will take 12 cycles as it is but if you swap R0 and
R1 it will take 17.
(Are you feeling a certain sense of Deja Vu? If not then my other posting
didn't get out. Doesn't suprise me...)
--
|- Nick Craig-Wood ---------------------------------- n...@axis.demon.co.uk -|
|- I'm lying in the shade of my family tree. I'm a branch that broke off --|
Rob. T
LDR R0,seed
ADD R0,R0,#13
EOR R0,R0,R0,ROR #9
STR R0,seed
Andy S.