Генерация случайного числа в диапазоне 0-9 в сборке x86 8086
Прежде всего, я новичок в сборке 8086, и мне было довольно сложно получить знания. Тем не менее, я сделаю все возможное.
Я пытался написать код для генерации случайного числа в диапазоне 0-9. Изучив несколько примеров и предложений, я остановился на этом. Для простоты я не применил математическую функцию к найденному счетчику часов, а также подумал, что это не нужно. В результате по некоторым причинам я генерировал определенное число, например, в 6,7 раза меньше, чем числа, такие как 1,3 и 9. Я считаю, что это потому, что я беру меньший порядок тактов, где значения меняются так, быстро.
Моя цель - смоделировать бросок костей, который позже изменит диапазон кодов ниже на 1-6. Мой вопрос: достаточно ли это для моей цели? или есть ли лучший способ сделать это?
коды:
RANDGEN: ; generate a rand no using the system time
RANDSTART:
MOV AH, 00h ; interrupts to get system time
INT 1AH ; CX:DX now hold number of clock ticks since midnight
; lets just take the lower bits of DL for a start..
MOV BH, 57 ; set limit to 57 (ASCII for 9)
MOV AH, DL
CMP AH, BH ; compare with value in DL,
JA RANDSTART ; if more, regenerate. if not, continue...
MOV BH, 49 ; set limit to 48 (ASCII FOR 0)
MOV AH, DL
CMP AH, BH ; compare with value in DL
JB RANDSTART ; if less, regenerate.
; if not, this is what we need
mov ah, 2h ; call interrupt to display a value in DL
int 21h
RET
Ответ от @johnfound:
Я обнаружил, что его путь проще и требует меньше времени для генерации случайного числа. Он упомянул, что это работает, только если вам нужно одно случайное число, или интервал между случайными числами включает паузы для ввода человеком. В противном случае числа не будут случайными вообще (я полагаю, что из-за времени, которое мы первоначально берем, не изменяется). Это хорошо для моего случая, так как я имитирую игральные кости, и мне нужно вмешательство пользователя (еще один бросок), прежде чем я снова буду запускать код.
RANDGEN: ; generate a rand no using the system time
RANDSTART:
MOV AH, 00h ; interrupts to get system time
INT 1AH ; CX:DX now hold number of clock ticks since midnight
mov ax, dx
xor dx, dx
mov cx, 10
div cx ; here dx contains the remainder of the division - from 0 to 9
add dl, '0' ; to ascii from '0' to '9'
mov ah, 2h ; call interrupt to display a value in DL
int 21h
RET
Что он сделал: 1. Мы переместили значение в DX в AX 2. Мы очистили DX. 3. Мы переехали 10 декабря в CX. 4. Мы разделили AX на CX, следовательно, мы получаем остаток в пределах 0-9 декабря, который сохраняется в DX 5. Наконец, мы добавили ASCII '0' (dec 48) к DX, чтобы получить их в ASCII '0' до '9',
2 ответа
Этот прием работает только в том случае, если вам нужно одно случайное число или интервал между случайными числами включает паузы для ввода человеком. Во всех остальных случаях числа не будут случайными вообще.
Если вам нужно много случайных чисел, то существуют разные алгоритмы псевдослучайных чисел.
Еще одно замечание: есть более простой способ получить число в нужном интервале:
mov ax, dx
xor dx, dx
mov cx, 10
div cx ; here dx contains the remainder of the division - from 0 to 9
add dl, '0' ; to ascii from '0' to '9'
Вы можете использовать этот метод для каждого генератора случайных чисел, конечно.
Для этой работы я нашел меньший код операции AAM - Ascii Adjust for Multiplication. Как работает этот код операции:
AH := AL / 10
AL := AL mod 10
Итак, это будет так:
mov al, dl
aam
add al, '0'
mov dl, al