测试一个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这三个寄存器的值。