2015-03-27 2 views
-1

Он не генерирует предполагаемую случайность.Как посеять для генерации случайных чисел?

Я думал, начиная с семени, как $ 66 и xoring два последних младших бит, и ROR даст мне следующее случайное число и так далее, но он показывает только $ B3 и не меняется вообще.

Как я должен питаться? Строка выше случайного отображает номер на portc, поскольку я хочу, чтобы два числа отображались друг за другом.

Я использую avr studio 4 для atmega 8535 в 1Mhz.

> ;Program to random numbers on port C 
> 
> ;Stack and Stack Pointer Addresses .equ  SPH =$3E    
> ;High Byte Stack Pointer Address .equ  SPL =$3D    
> ;Low Byte Stack Pointer Address 
> 
> .equ  RAMEND =$25F    ;Stack Address 
> 
> ;Port Addresses 
> 
> .equ  PORTC =$15    ;Port C Output Address 
> 
> .equ  DDRC =$14    ;Port C Data Direction Register 
> Address 
> 
> .equ  numberoneddr=DDRC 
> 
> .equ  numberoneport=portc 
> 
> .equ  numbertwoddr=DDRC 
> 
> .equ  numbertwoport=portc 
> 
> .equ  delayCount=21 
> 
> .equ random1 =$66 
> 
> ;Register Definitions 
> 
> .def numberone =r1    ;Register to store data pointed 
> to by Z 
> 
> .def numbertwo =r2 
> 
> .def  temp =r16    ;Temporary storage register 
> 
> 
> 
> reset: 
> 
> ; initialize stack pointer. Done automatically at reset on many AVRs 
> 
> ldi temp, low (RAMEND) 
> 
> out spl, temp 
> 
> ldi temp, high (RAMEND) 
> 
> out sph, temp 
> 
> 
> 
> 
> ;port initialisation 
> 
> ldi temp,$FF 
> 
> out numberoneddr,temp 
> 
> out numberoneport,temp 
> 
> out numbertwoddr,temp 
> 
> out numbertwoport,temp 
> 
> 
> 
> ;Program Initialisation 
> 
> ldi temp,$66 
> 
> rcall random 
> 
> mov numberone, temp 
> 
> out numberoneport,numberone 
> 
> rcall random 
> 
> mov numbertwo, temp 
> 
> out numberoneport,numbertwo 
> 
> 
> 
> 
> random: mov r19,temp 
> 
> ldi r17, 0x01 
> 
> eor r19,r17 
> 
> ror r19 
> 
> mov temp,r19 
> 
> ret 
> 
> 
> 
> delay: 
>   clr r20 
> 
>  clr r21 
> 
>  ldi r22, delayCount 
> 
> loopDelay: 
> 
>  dec r20 
> 
>  brne loopDelay 
> 
>  dec r21 
> 
>  brne loopDelay 
> 
>  dec r22 
> 
>  brne loopDelay 
> 
>   ret 
+0

использовать блок кода (или собираетесь на 4 пробелы) для исходного кода, добавьте больше информации, как MCU, что именно не так, ... ваш код работает на ПК? если не пытаться проследить его, что не так ... и порт для MCU asm, когда он работает. Если на вашем MCU есть возможности точки останова/трассировки, вы можете пропустить часть ПК. Прямо сейчас ваш вопрос на самом деле, почему этот код не работает, который не соответствует теме, поэтому голосование за закрытие на данный момент – Spektre

+0

не генерирует предполагаемую случайность, я научился начинать с семени, как 66 долларов, и xoring два последних младших бит и ror дал бы мне следующий случайный номер и так далее, но он показывает только $ B3 и не изменится вообще. Любая помощь будет оценена по тому, как я использую только avr studio 4 для atmega 8535 на 1Mhz – alex

+0

вы кормите 'temp = $ 66 'каждый случайный вызов, поэтому результат всегда один и тот же ... вы должны подавать температуру только один раз. также я бы добавил своп бит (а не просто 'ror'), который обычно ведет к лучшей случайности. также, какие 3 строки выше 'random:' label do ... они не выполняются на 'call random' !!! – Spektre

ответ

1

После некоторого поиска на основе древних источников ASM кода архивов шахты Я нашел это для платформы x86 MSDOS NASM я использую в те дни:

;.rnd  ;al=rnd num <0,ah>; 

.rnd: pusha 
    mov cx,ax 

.rnd0: mov bx,[cs:.rnddat] 

    mov ax,[cs:.rndtim] 
    xor al,bh 
    add ah,bh 
    rcr ax,3 
    xor al,bl 
    rcl ax,2 

.rnd2: cmp al,ch 
    jbe .rnde 
    sub al,ch 
    or ch,ch 
    jnz .rnd2 
    sub al,al 

.rnde: mov ah,bl 
    mov [cs:.rnddat],ax 
    or al,1 

    xor ax,[fs:046Ch] 
    add [cs:.rndtim],ax 
    popa 
    mov al,[cs:.rnddat] 
    ret 
.rnddat:db 0,0 
.rndtim:dw 0 

Идея состоит в том, чтобы иметь некоторый сохраненный номер у некоторые базовые операции ALU, такие как +,*,/,<<,>>,&,^, но убедитесь, что не происходит насыщения и, как правило, замена H,L некоторой ценности, чтобы держать случайность под контролем. Поэтому отправьте это на ваш asm, но я настоятельно рекомендую его закодировать и сначала попробуйте на ПК, чтобы узнать, насколько случайность в порядке для вашей задачи.

BTW вы также можете использовать программную память или любое содержимое ПЗУ в качестве базы для случайности ... это также эксплуатирует внутренний блокRTC, так что вы должны пропустить эту часть или добавить таймер или только петлю через кучу вместо пустых данных.

[0000:046C] are 4 Bytes master clock count (long integer) 0 = midnight and increments until a 24 hour equiv. 

я нашел даже старую демо прииск NoSignal (с 1997 года в TASM), которые RND внутри:

.386P 
    IDEAL 
    MODEL TINY 

    CODESEG 
    STARTUPCODE 
main: mov ax,19 ;320*200*256 
    int 16 
    push 0A000h ;Video segment 
    pop es  ;keyboard test,speaker delay v si=256 

l0: ror ax,cl  ;rnd...ax 
    add ax,di 
    stosw  ;plot... 
    loop r1  ;speaker delay... 
    mov cx,si 
    out 61h,al 
r1: or di,di 
    jnz l0 
    push ax 
    mov ah,1 ;test keyboard 
    int 16h 
    pop ax 
    jz l0 

ende: sub ax,ax ;turn off speaker and exit 
    out 61h,al 
    int 16h 
    mov ax,3 
    int 16 
    ret 
    END 

Это заполнить экран и динамик с белым шумом, как будто нет антенный кабель аналогового ТВ , Эта версия 44 байт длиной, псевдо генератор случайных чисел начинается с ярлыком l0:

  • ax является сгенерированным числом (а также prevvious сгенерированное число, как вы температура)
  • di является приращение (что-то вроде фактического времени) .. .
  • cl является декремента

так, если я смотрю на это право должно быть достаточно:

rnd:ror ax,cl  ;rnd...ax 
     add ax,di 
     inc di 
     dec cl 
     ret 

и добавить push/pop хранить регистры/значения, если необходимо. Если вам нужно что-то более сложное, используйте modulo prime arithmetics.

[edit1] простой C++ псевдослучайного генератора

WORD rnd_d0=0x66; // these are seed numbers if not selected right then the randomness is not good 
WORD rnd_d1=0x5A; // these give fairly good results 
WORD rnd_d2=0xC3; 
WORD rnd() 
    { 
    rnd_d0^=rnd_d1|rnd_d2; // xor 
    rnd_d1*=rnd_d2; // mul 
    rnd_d2+=rnd_d1; // add 
    rnd_d0=(rnd_d0<<8)|(rnd_d0>>8); // 8bit halves swap 
    return rnd_d0; 
    } 

Вышеуказанные генераторы случайных был обтянутое время DOS окружающей среды или специального использование. Это не ...Случайность как это:

randomness graph

, когда я использую его, чтобы заполнить окно изображения NoSignal результат заключается в следующем:

NoSignal

и здесь Gif анимации:

NoSignal 320x240x3

NoS ignal заполнить код, как это:

for (int y=0;y<ys;y++) 
    for (int x=0;x<xs;x++) 
    pyx[y][x]=0x00010101*int(rnd()>>8); 

Так что высокий 8bit из псевдо-случайного числа 16bit используется умножение только преобразует этот 8bit число в шкале серого цвета.

  • xs,ys является размером
  • pyx изображения прямого указателем изображения к его линии

Не изменять число семян без надлежащего тестирования с этим на ПК

Ошибочно выбранные семян вообще не приводит к случайности. Если вы хотите безопасно семена (без тестирования), то семя с предоставленными константами, а затем вызовите rnd() столько же раз, сколько и ваш новый номер семени. Разоренный это прямо сейчас, так что может быть лучше семена для этого, это только первые, я обнаружил, что дает неплохие результаты

Эти семена также хороши:

WORD rnd_d0=0x37A6; 
    WORD rnd_d1=0x377A; 
    WORD rnd_d2=0x3BC3; 
+0

У @alex было немного времени для этого, поэтому я протестировал свои старые случайные генераторы и без времени MSDOS или специального способа использования там не так хорошо, поэтому я создал что-то, что является платформой и независимым от использования см. в [edit1], он использует 16-битный ALU, поэтому, если у него нет кода, то из 8-битного источника ALU находится на C++, поэтому не должно быть никаких проблем с портированием в asm , Если вам нужно что-то лучше, то укажите необходимые свойства случайности. – Spektre

+0

Поворот-перенос ('rcr' /' rcl') с count> 1 довольно медленный на современных x86: 8 uops на Intel Haswell, например, или 15 м- ops на AMD Steamroller. Это, я думаю, оптимизирован для размера кода, а не для скорости и/или для гораздо более старых процессоров. (даже ранние процессоры P6, такие как PII, имели более быстрый rcr). –

+0

@PeterCordes, который больше походил на AMD 80386 до AMD K5 ... и да, он был оптимизирован для длины кода – Spektre

Смежные вопросы