首页
社区
课程
招聘
[旧帖] 求段汇编概率代码 0.00雪花
发表于: 2010-12-28 12:15 5492

[旧帖] 求段汇编概率代码 0.00雪花

2010-12-28 12:15
5492
求段汇编概率代码

代码老实写不好啊。用处想在小游戏里加个概率程序

具体的思路:

1.读取概率[这块代码我会]

2.概率代码

3.成功 或者 失败

工具OD 。

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (15)
雪    币: 37
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
;取系统时间,ch小时,cl分钟,dh秒,dl1/100秒
  mov ah,2ch           
  int 21h
可以用dl做概率
2010-12-28 12:41
0
雪    币: 239
活跃值: (25)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
以前我也是用这个做过,好像有一定范围。不知道你是怎么算的呀
2010-12-28 12:46
0
雪    币: 41
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
但是概率是我自定义的
2010-12-28 12:51
0
雪    币: 37
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
比如你概率31%,如果取出的dl小于31,就可以认为这个事件发生了
2010-12-28 12:54
0
雪    币: 41
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
能否给出具体代码啊 关于int 我还真不太懂啊
2010-12-28 12:57
0
雪    币: 41
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
0046B615   >  D94424 20        fld dword ptr ss:[esp+20]
0046B619   > |D815 A0644F00    fcom dword ptr ds:[4F64A0]
0046B61F   . |DFE0             fstsw ax
0046B621   . |F6C4 41          test ah,41
0046B624   . |75 0A            jnz short jfsa.0046B630
0046B626   . |DDD8             fstp st
0046B628   . |D905 A0DD4F00    fld dword ptr ds:[4FDDA0]
0046B62E   . |EB 15            jmp short jfsa.0046B645
0046B630   > |D815 E0784F00    fcom dword ptr ds:[4F78E0]
0046B636   . |DFE0             fstsw ax
0046B638   . |F6C4 05          test ah,5
0046B63B   . |7A 08            jpe short jfsa.0046B645
0046B63D   . |DDD8             fstp st
0046B63F   . |D905 E0784F00    fld dword ptr ds:[4F78E0]

在某个程序发现这段概率代码 可惜不太明白
2010-12-28 13:02
0
雪    币: 37
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
Probability EQU  31 ;你自己定义的概率百分比,比如31%,则Probability为31
mov ah,2ch      ;取系统时间   
int 21h
cmp dl,Probability ;相当于取随机数,判断事件概率,是否大于设定值
jl  label;小于则发生,跳到事件处理代码
;否则没有发生,对应的处理代码

label: ;事件发生处理代码处
2010-12-28 13:04
0
雪    币: 41
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
o(︶︿︶)o 唉 基础不好。问下od怎么写啊 第一句话就不知道怎么写了啊
2010-12-28 13:07
0
雪    币: 41
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
为什么执行到int 21h 这句话 访问违规呢?
2010-12-28 14:02
0
雪    币: 35
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
新人好受限制啊
2010-12-30 19:37
0
雪    币: 6092
活跃值: (654)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
12
很新颖的东西
2010-12-31 14:05
0
雪    币: 93
活跃值: (55)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
13
你的意思是说,
你已经获得了一个随机数x(0<=x<=max),还有一个概率y%,
现在要进行一次随机?

汇编我不会,不过伪代码如下:
if(x/max*100<=y)
  then return true
  else return false;

比如x=100(0<=x<=256,max=256),y%=50%,也就是y=50
那么判断 100/256*100与50的大小关系~
2011-1-1 10:37
0
雪    币: 29
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
能否给出具体代码啊 关于int 我还真不太懂啊
2011-1-1 15:06
0
雪    币: 349
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
PROBABILITY EQU 31 ;概率值
isHappen proc
rdtsc ;取随机数种子
mov ecx,100
div ecx;求模,模在edx
cmp edx,PROBABILITY
jle @F
xor eax,eax
ret
@@:
mov eax,1
ret
isHappen endp

代码比较简单,特别是随机数偷懒了。概率值为0---100,当然不可以等于0,也不可以等于100,否则不合常理,这两个特殊情况要用到就自己加吧。
2011-1-1 15:36
0
雪    币: 93
活跃值: (55)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
16
这段代码将测试一次概率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比较好
2011-1-1 15:37
0
游客
登录 | 注册 方可回帖
返回
//