随机数

测试一个win32 asm的随机数算法:

        .386
        .model flat, stdcall
        option casemap :none
        
include        windows.inc
include        kernel32.inc
include         msvcrt.inc
includelib    kernel32.lib
includelib      msvcrt.lib


        .data
seed            dd       108f22afh
;count           dd       0
        .const
szFmt           db      '%d ',0dh,0ah,0
szFmts          db      '%*d',0dh,0ah,0
;newLine         db       0dh,0ah,0

        .code

_random PROC base:DWORD         
    mov eax, seed             
    xor edx, edx
    mov ecx, 127773
    div ecx
    mov ecx, eax
    mov eax, 16807
    mul edx
    mov edx, ecx
    mov ecx, eax
    mov eax, 2836
    mul edx
    sub ecx, eax
    xor edx, edx
    mov eax, ecx
    mov seed, ecx
    div base
    mov eax, edx
    ret
_random ENDP
start:
                pop edi
                
                mov edi,20
STA:
                cmp edi,1
                ;无符号数比较 jump if below,即前者小于后者则转移
                jb EXIT
                invoke _random,15
        ;注意:addr左边不能为eax  貌似执行完pritf后会改变ecx 
                invoke crt_printf,addr szFmt,eax
                dec edi
                jmp STA
EXIT:          
                invoke crt_scanf,addr szFmts  ;暂停
                push edi
        invoke    ExitProcess,NULL
end    start

图:

上图每次运行程序产生的数是都是一样的,是因为种子相同。

怎么样变成“随机数”(实际我们rand的随机数是伪随机只是周期很大)?

与程序窗口句柄或者进程句柄进行运算可以使程序每次打开产生的随机数不同。

注意:

上面的程序若用ecx进行循环是不行的,原因是c语言的printf会改变ecx的值!

自己调试一下便可知。

已经有人问过此问题:

printf函数在调用过以后会改变寄存器的值。一般会改变eax,ecx,edx这三个寄存器的值。

http://www2.zzu.edu.cn/qwfw/faqs/list.asp?id=2

 

posted @ 2013-12-07 14:26  乾卦  阅读(272)  评论(0编辑  收藏  举报