这段代码将测试一次概率y/x,结果保存在eax中
1. r=GetTickCount()(这个函数不懂?返回自windows启动以来的毫秒数)
2. b=r mod a,这样b/a是一个0至1的小数
3. 比较b/a和y/x,当b/a<=y/x时,返回eax=1,否则eax=0
对于第1步,
因为GetTickCount的值随机性不强,所以可以进行适当变换
1.1. r=GetTickCount()
1.2. r=各种变来变去(r)
对于第3步,
比较b/a和y/x,相当于比较b*x和y*a,所以第3步如下进行
3.1. m=b*x
3.2. n=y*a
3.3. eax=(m<=n)?1:0,在代码中,我将(m<=n)改为(n>=m)。
================================================================
1.1.
首先取得一个随机数r
00401020 >call kernel32.GetTickCount ; [GetTickCount
1.2.
然后对r进行一定变换,因为GetTickCount的结果是单调递增的,随机性不好
00401025 mov edx, eax ; 对r进行变换
00401027 rol eax, 1
00401029 xor eax, edx
0040102B rol eax, 3
0040102E xor eax, edx
00401030 rol eax, 7
00401033 xor eax, edx
00401035 rol eax, 15
00401038 xor eax, edx
2.
b=r mod a,使用64位除法以防除法溢出
同时a为16位数,这样可以使b也为16位数
执行后a=ecx,b=ebx
0040103A mov ecx, 0D4DD ; a=0xD4DD,16位素数
0040103F xor edx, edx
00401041 div ecx ; b=r mod a
00401043 mov eax, edx
3.1.
m=b*x,x为16位数,b也为16位数,结果为32位数,正好存在eax中
执行后m=ebx
00401045 mov edx, 64 ; x=0x64=100,16位整数
0040104A mul edx ; m=b*x
0040104C mov ebx, eax
3.2.
n=y*a,y为16位数,a也为16位数,结果为32位数,正好存在eax中
执行后n=eax
0040104E mov eax, ecx ; eax=a
00401050 mov edx, 32 ; y=0x32=50,16位整数
00401055 mul edx ; n=a*y
3.3.
比较n和m,当n>=m时,eax=1,否则eax=0。
00401057 cmp eax, ebx
00401059 mov ecx, 0
0040105E mov edx, 1
00401063 cmovge ecx, edx
00401066 mov eax, ecx ; eax=(n>=m)?1:0
呃,补充一下,
如果要写成函数,那个x和y要改成函数的参数,
比如mov edx, 64
可能改为mov edx,[ebp-8]之类的~
再补充一下,
这个GetTickCount的精度是1毫秒,
所以如果你要非常频繁的调用这个函数
那么你还是用其他方法得到r比较好