; ----------------------------- MOTHER.ASM ----------------------------- ; Mother-of-All random number generator by Agner Fog 1998 ; 32-bit mode version for 80x86 and compatible microprocessors ; ; MRandom returns a floating point number between 0 and 1. ; MRandomInit must be called before the first call to MRandom. ; ; C++ prototypes: ; extern "C" void MRandomInit (int seed); ; extern "C" double MRandom (void); ; extern "C" int MIRandom (int min, int max); ; ; © 1998, 2004 Agner Fog. ; GNU General Public License www.gnu.org/copyleft/gpl.html ; ---------------------------------------------------------------------- ; The MRandom function is optimized for the Pentium microprocessor. iglobal mf3 dd 2111111111 ; factors mf2 dd 1492 mf1 dd 1776 mf0 dd 5115 endg uglobal m0 dd ? ; history buffer m1 dd ? m2 dd ? m3 dd ? mc dd ? temprng dq ? ; used for conversion to float endg proc init_random mcall 26, 10 ; seed xor ecx, ecx ; make random numbers and put them into buffer @@: imul eax, 29943829 dec eax mov [m0+ecx*4], eax inc ecx cmp ecx, 5 jb @r push edi mov edi, 19 @@: call MRandom fstp st0 dec edi jnz @r pop edi ret endp proc MRandom call MBRandom ; random bits mov edx, eax ; fast conversion to float shr eax, 12 or eax, 3ff00000h shl edx, 20 mov dword[temprng+4], eax mov dword[temprng], edx fld1 fld [temprng] ; partial memory stall here fsubr st0, st1 ret endp proc MIRandom, max, min ; make random integer in desired interval call MBRandom ; make random number mov edx, [max] mov ecx, [min] sub edx, ecx js .error ; max < min inc edx ; max - min + 1 mul edx ; multiply random number by interval and truncate lea eax, [edx+ecx] ; add min ret .error: mov eax, 80000000h ; error exit ret endp proc MBRandom push edi mov eax, [mf3] mul [m3] ; x[n-4] mov ecx, eax mov eax, [m2] ; x[n-3] mov edi, edx mov [m3], eax mul [mf2] add ecx, eax mov eax, [m1] ; x[n-2] adc edi, edx mov [m2], eax mul [mf1] add ecx, eax mov eax, [m0] ; x[n-1] adc edi, edx mov [m1], eax mul [mf0] add eax, ecx adc edx, edi add eax, [mc] adc edx, 0 mov [m0], eax mov [mc], edx pop edi ret endp