Seed dw ?
;...
Random proc near
; Получить случаное число в интервале 0..MaxRandom (в стеке)
; Результат вернуть в регистре ax
push bp
mov bp,sp
pusha
mov ax,Seed
mov cx,8
@NewBitmov bx,ax
and bx,002dh
xor bh,bl
clc
jpe @shift
stc
@shift rcr ax,1
loop @NewBit
mov Seed,ax
mov ah,0
xor dx,dx
mov bx,[bp+4]
; bx = Максимально допустимое число
add bl,1
adc bh,0
div bx
mov [bp+4],dx
popa
mov ax,[bp+4]
; Результат вернем в виде слова
pop bp
ret 2
Random endp
Randomize proc near
push ds
push 0040h
pop ds
push word ptr ds[006ch]
; Read current BIOS ticks
pop word ptr ssSeed
pop ds
retn
Randomize endp
Рандом на асме
Кто-нить подскажите плз как организовать рандом на асме.....
Вообщето в пасе рандом организовывается с помощью системного таймера, попробуй и здесь как - нибудь так же.
Поэтому удобнее, на мой взгляд, использовать счетчик тактов, который изменяет значение с каждым тактом процессора и имеется во всех моделях, начиная с Pentium. Он вызывается ОДНОЙ командой RDTSC (код 0Fh 31h - на тот случай, если Ассемблер ее не поймет) и помещает результат в пару регистров EDX:EAX, так что можно СРАЗУ брать нужное число из EAX. Единственное ограничение - должен быть сброшен бит TSD в регистре CR4 (кажется, это бит 2), либо нужно выполнять эту команду в нулевом кольце защиты (правда, для программ, работающих под DOS или в режиме эмуляции DOS это не имеет значения - они уже работают на этом уровне).
На самом деле таймер не надо программировать - есть ячейка 0040[006ch], значения котрой гораздо чаще меняются, чем 1/18 - см. ниже
Код:
1) Программируемый счетчик интервалов Intel 8253/8254 работает на частоте 1.18 Мгц и имеет три независимых счетчика тактов. Два из них используются при регенерации памяти (счетчик 1) и для управления динамиком (счетчик 2), а третий (счетчик 0) как раз и используется в качестве системного таймера. Он настраивается таким образом, что через каждые 65535 тактов (что и составляет 18.2 раза в секунду) вызывается прерывание IRQ0 (INT , обработчик которого как раз и увеличивает содержимое ячейки по адресу 0040h006ch на единицу. Этот счетчик можно перепрограммировать (через порты 40h-43h), задав начальное значение меньше 65535, тогда прерывание будет происходить чаще. Но делать этого не стоит, так как это, скорее всего, собьет все системные часы (они начнут идти быстрее), использующие как раз этот счетчик.
2) Часы реального времени (RTC), являющиеся частью системы CMOS. Они работают на частоте 32,768 КГц и используют IRQ8 (INT 70h), но соответствующая подпрограмма обрабатывает только ситуацию, когда текущее время совпадает с заранее заданным (с точностью до секунды), и никаких счетчиков при этом не используется. Можно запрограммировать эти часы на более частое прерывание (вплоть до 1000 раз в секунду), но тогда нужно написать свой обработчик прерывания INT 70h, который использовал бы какую-нибудь ячейку в качестве счетчика.
В обоих случаях имеем либо слишком маленькую периодичность изменения, либо риск испортить систему.
Другое дело, если таймер используется всего один раз - чтобы получить начальное значение для последовательности ПСЕВДОслучайных чисел.
Тут никаких проблем не будет, и ничего перепрограммировать не надо. А для получения последовательности СЛУЧАЙНЫХ чисел все-таки больше подойдет счетчик тактов.
[ Это Сообщение было отредактировано gerard в 2002-03-14 0434 ]
Цитата: gerard
Можно запрограммировать эти часы на более частое прерывание (вплоть до 1000 раз в секунду), но тогда нужно написать свой обработчик прерывания INT 70h, который использовал бы какую-нибудь ячейку в качестве счетчика.
[ Это Сообщение было отредактировано gerard в 2002-03-14 0434 ]
[ Это Сообщение было отредактировано gerard в 2002-03-14 0434 ]
А как это сделать?
Знатный бурильщик. Получаешь приз за самый глубокий подъём.
*пацталом*