来源（x86 Assembly）

**From:** http://www.programmersheaven.com/mb/x86_asm/234821/234834/re-random-nubmers/?S=B20000

This message was edited by Adusko at 2004-1-5 12:18:25

Is there any way to produce a random number in assebmler? Or what should i use instead? And how can I do some delay, if my program is running too fast?

Re: Random nubmers Posted by Bitdog on 5 Jan 2004 at 9:31 PM

Nasm code below gives numbers that appear random.

You might give it a try ?

I don't think a computer can do random ?

; ========================= RANDOM.INC ========================= ; Procedure, RANDOM, generates random numbers in AL reg (not many 38's though) ; It gets every number 0-255 with no appearant pattern in even amounts ; ; Call with, NOTHING ; ; Returns, AL = random number between 0-255, ; AX may be a random number too ? ; DW RNDNUM holds AX=random_number_in AL ; SEED DW 3749h RNDNUM DW 0 align 16 RANDOM: PUSH DX MOV AX,[SEED] ;; AX = seed MOV DX,8405h ;; DX = 8405h MUL DX ;; MUL (8405h * SEED) into dword DX:AX ; CMP AX,[SEED] JNZ GOTSEED ;; if new SEED = old SEED, alter SEED MOV AH,DL INC AX ; ROR AX,1 ;; old version missed #38 a lot GOTSEED: MOV WORD [SEED],AX ;; We have a new seed, so store it MOV AX,DX ;; AL = random number MOV WORD [RNDNUM],AX POP DX RET |

Random numbers - practical code Posted by peret on 6 Jan 2004 at 6:04 PM

: Is there any way to produce a random number in assebmler? ; a good linear regression RNG and a 32-bit primitive polynomial mod 2 dseg segment dword public use16 'DATA' random_word label word db -1 random_byte label byte ; for byte, take the TOP byte db -1 align 4 random_32 label word ; for byte/word take the lower dw -1,-1 dseg ends cseg segment para public use16 'CODE' assume cs:cseg,ds:dseg ; Linear regression generator x(n+1) = (2053*x(n) + 13849) mod 2^16 ; This is a good generator because (2053 mod 8)=5 (Knuth) and because ; 2053 and 13849 have no common factors. It meets the Nevada chi-squared ; standard when conventionally tested, but is a little too ; "perfect" on prolonged tests because of its short period. Curiously, ; it's utterly useless for shuffling a 52-card deck, where it delivers ; less than 10% of its results between 5% and 95% chi squared after ; a million shuffles. ; 2053 = 2^11 + 2^2 + 1, which is a known primitive polynomial modulo 2. ; The period is 65535. ; There are quicker ways to implement this. I use shift and add ; as an illustration rather than a recommendation. lr_random proc mov ax,[random_word] mov bx,ax shl ax,9 ; x 512 add ax,bx ; x 513 shl ax,2 ; x 2052 add ax,bx ; x 2053 add ax,13849 mov [random_word],ax ret lr_random endp ; Very fast polynomial 32-bit RNG ; Uses X32+X7+X5+X3+X2+X1+1 but any order-32 primitive polynomial will do, ; such as one of the 32-bit CRC generators. The period is 2^32 -1 ; There is some sequential correlation, easily broken up with a Bays ; Durham shuffle. I've extensively tested this generator and it passes ; all the standard tests, including the million-shuffle test that the ; LR generator fails, producing text-book chi squared curves time after ; time. Theoretically an order 31 polynomial would do better, since ; 2^31-1 is prime but 2^32-1 shares at least one common factor with about ; 23% of all the integers in the period ... This can give rise to short ; cycles if you are careless. poly_random proc clc ; clear carry test word ptr[random_32].2,8000h ; test outgoing bit jz short @F ; clear, no XOR xor word ptr[random_32],0057h ; else do the deed stc ; and set carry to shift in @@: rcl dword ptr[random_32],1 ; do the shift ret poly_random endp cseg ends end |