Генерация последовательности случайных чисел
Таким способом можно получить начальное значение из диапазона 0..59. Для получения большего по величине начального значения можно использовать величину размером 32 бита из области данных BIOS по адресу 0040:006с. Здесь содержится счетчик прерываний от таймера. Извлечь это значение можно, используя следующий программный фрагмент:
push ds push 40h pop ds mov eax.dword ptr ds:006ch popds
Заменяя команду MOV командами MOV AX,word ptr ds:006ch или MOV AL, byte ptr ds:006ch, можно использовать младшие 8 или 16 бит значения из этой области BIOS. Команда MOV AL, byte ptr ds:006ch позволяет случайным образом получить в регистре AL значение из диапазона 00. .f fh.
Попытки создать программный датчик случайных чисел без опоры на какую-либо теорию обречены на провал. Рассмотрим еще несколько способов генерации случайных чисел.
Аддитивный генератор случайных чисел
Генератор, формирующий очередное случайное число в соответствии с отношением (3), называется аддитивным:
Xn+1=(Xn+Xn-k) mod m. (3)
В трехтомнике Кнута [5] обсуждаются подобные генераторы и рекомендован следующий вариант формулы (3):
Xn+1=(Xn-24+Xn-55) mod m.(4)
Здесь n > 55, m=21, Хо,…, Х54 – произвольные числа, среди которых есть и нечетные. При этих условиях длина периода последовательности равна 21 -1 (255 -1).
Для генерации первых 55 случайных чисел можно использовать один из рассмотренных выше генераторов. Возьмем датчик линейной (смешанной) конгруэнтной последовательности случайных чисел (с > 0).
;rand_add.asm – аддитивный генератор случайных чисел. :Вход::Х0. а. с .m; ;Случайная последовательность длиной 55 значений, ; получаемая с помощью программы генерации высокослучайных ; двоичных наборов (см .rand_mix_cong_1.asm); :N=700 – количество элементов в последовательности + 1; :L=7 – значение степени т=27. :Выход: dl – значение очередного случайного числа. .data N=700 количество элементов в последовательности + 1 L=7:L – значение степени т=2 т db 128;128=27 mm dw 256; 256=28 a db 9 с dw 3 ;массив значений х (начальное значение х=3) длиной N+1 х db 3, N dup (Offh) ;……… .code :далее фрагменты из rand_mix_cong_l.asm. хоr si,si mov ecx.54:счетчик цикла для формирования начальной последовательности :первое число в последовательности х=3 mov al,x cycl: вычисляем очередное случайное число Х=(а*Х) mod m mul a;а*х в ah:al add ax.с shrd ax.ax.L:L – значение степени т=27 хоr al.al rol ax.L;в al случайное число :вывод в массив х и файл – командная строка rand_mult_cong.exe > p.txt i nc si mov x[si].al mov dl.al mov ah. 02 int 21h loop cycl :далее продолжаем формирование случайной последовательности, но уже аддитивным методом mov ecx,N-55 cycl 2: incsi хоr dx.dx mov al.x[si-24] mov dl.x[si-55] add ax.dx хоr dx.dx div mm mov x[si].dl mov ah.02 int 21h loop eye 12 exit:
Судя по результатам, этот метод достаточно хорош. В частности, он неплох тем, что позволяет задавать длину последовательности без оглядки на значение т.
Следующий рассматриваемый нами датчик можно использовать в программах на языке ассемблера для получения случайной последовательности 0 и 1.