001  ;**************************************************
002  ;    以下代码由“老罗代码着色器”0.2版进行着色
003  ;    测试文件名:Random.asm
004  ;    测试日期:  2002-12-29
005  ;**************************************************
006  
007  ;*********************************************************
008  ;程序名称:随机数的产生原理与实现
009  ;作者:罗聪
010  ;日期:2002-11-21
011  ;出处:http://www.LuoCong.com(老罗的缤纷天地)
012  ;注意事项:如欲转载,请保持本程序的完整,并注明:
013  ;转载自“老罗的缤纷天地”(http://www.LuoCong.com)
014  ;*********************************************************
015  
016  .386
017  .model flatstdcall
018  option casemap:none
019  
020  include \masm32\include\windows.inc
021  include \masm32\include\kernel32.inc
022  include \masm32\include\user32.inc
023  includelib \masm32\lib\kernel32.lib
024  includelib \masm32\lib\user32.lib
025  
026  WndProc         proto :DWORD, :DWORD, :DWORD, :DWORD
027  iRand           proto :DWORD, :DWORD
028  
029  .const
030  IDC_BUTTON_GENERATE equ 3000
031  IDC_EDIT_FIRST      equ 3001
032  IDC_EDIT_SECOND     equ 3002
033  
034  .data
035  szDlgName           db  "lc_dialog", 0
036  szCaption           db  "Rand Number Generator by LC", 0
037  szText              db  255 dup(0)
038  szTemplate          db  "(%d ~ %d)随机数:", 13, 10, 13, 10,\
039                          "         %d", 13, 10, 13, 10,\
040                          "老罗的缤纷天地", 13, 10,\
041                          "http://www.LuoCong.com", 0
042  nFirst              dd  0
043  nSecond             dd  0
044  
045  .code
046  main:
047      invoke GetModuleHandle, NULL
048      invoke DialogBoxParam, eaxoffset szDlgName, 0, WndProc, 0
049      invoke ExitProcess, eax
050  
051  WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
052      LOCAL hEdit: HWND
053  
054      .if uMsg == WM_CLOSE
055          invoke EndDialog, hWnd, 0
056          
057      .elseif uMsg == WM_COMMAND
058          mov eax, wParam
059          mov edxeax
060          shr edx, 16
061          movzx eaxax
062          .if edx == BN_CLICKED
063              .if eax == IDCANCEL
064                  invoke EndDialog, hWnd, NULL
065              .elseif eax == IDC_BUTTON_GENERATE || eax == IDOK
066                  ;获得上限:
067                  invoke GetDlgItemInt, hWnd, IDC_EDIT_FIRST, NULL, TRUE
068                  mov nFirst, eax
069                  ;获得下限:
070                  invoke GetDlgItemInt, hWnd, IDC_EDIT_SECOND, NULL, TRUE
071                  mov nSecond, eax
072                  ;产生随机数:
073                  invoke iRand, nFirst, nSecond
074                  ;输出:
075                  invoke wsprintf, addr szText, addr szTemplate, nFirst, nSecond, eax
076                  invoke MessageBox, hWnd, addr szText, addr szCaption, MB_OK or MB_ICONINFORMATION
077              .endif
078          .endif
079      .else
080          mov eaxFALSE
081          ret
082      .endif
083      mov eaxTRUE
084      ret
085  WndProc endp
086  
087  ;**********************************************************************
088  ; 函数功能:产生范围从 first 到 second 的随机数
089  ; 传入参数:
090  ;           first  = 下限
091  ;           second = 上限
092  ; 返回参数:
093  ;           eax = Rand_Number
094  ; 所用公式:
095  ;           Rand_Number = (Rand_Seed * X + Y) mod Z
096  ; 补充说明:
097  ;           (1)本例中用 GetTickCount 来取得随机数种子,
098  ;              在实际应用中,可用别的方法代替。
099  ;           (2)要产生随机数,X和Y其中之一必须是素数,
100  ;              所以 X = 23, Y = 7(可用别的素数代替)
101  ;**********************************************************************
102  iRand   proc uses ecx edx first:DWORD, second:DWORD
103      invoke GetTickCount ; 取得随机数种子,当然,可用别的方法代替
104      mov ecx, 23         ; X = ecx = 23
105      mul ecx             ; eax = eax * X
106      add eax, 7          ; eax = eax + Y (Y = 7)
107      mov ecx, second     ; ecx = 上限
108      sub ecx, first      ; ecx = 上限 - 下限
109      inc ecx             ; Z = ecx + 1 (得到了范围)
110      xor edxedx        ; edx = 0
111      div ecx             ; eax = eax mod Z (余数在edx里面)
112      add edx, first      ; 修正产生的随机数的范围
113      mov eaxedx        ; eax = Rand_Number
114      ret
115  iRand   endp
116  
117  end main
118  ;********************   over    ********************
119  ;by LC