x86 Assembly - Random nubmers

来源(x86 Assembly)

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

Posted by Adusko on 5 Jan 2004 at 11:52 AM

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
        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
        MOV     WORD [SEED],AX      ;; We have a new seed, so store it
        MOV     AX,DX               ;; AL = random number
        MOV     WORD [RNDNUM],AX
        POP     DX

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
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
poly_random    endp

cseg    ends

Link: http://www.asm32.net/article_details.aspx?id=4377

浏览次数 177 发布时间 2008-12-14 17:43:19 从属分类 DOS汇编编程 【评论】【 】【打印】【关闭
| www.asm32.net | 2006版 | 资料中心 | linux | asm/asm32 | C/C++ | VC++ | java | Python | 书签 | ASP.Net书签 | 京ICP备09029108号-1