Иллюстрированный самоучитель по задачам и примерам Assembler

Генерация последовательности случайных чисел

Таким способом можно получить начальное значение из диапазона 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.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.