实验题目3:随机数产生与仿真36选7的开奖过程,完整仿真抽奖过程
注:这是学校的汇编实验作业,今天就把实现的过程跟大家分享一下。之前在网上有参考过其他人写的这个题目的汇编程序,他的思路是每次按下Enter键抽出一个随机数,然后判断是否已经抽过,如果已经存在,则重新取数,实际上这并没有完全仿真,因为这样导致每个数被抽到的概率不同。
我的改进思路是这样的:先定义一个数组,初始化。每次按下Enter键抽取一个随机数,然后把这个随机数数作为数组的下标,把对应的数组下标的值输出,然后把当前的数组下标的元素与当前数组的最后一个元素交换,接着把数组长度减一(也可以把数组下标后面的所有元素都往前移一位,然后数组长度减一)
首先是定义好数据段的数组,并且初始化
s2 segment
arr db 1,2,3,4,5,6
db 7,8,9,10,11,12
db 13,14,15,16,17,18
db 19,20,21,22,23,24
db 25,26,27,28,29,30
db 31,32,33,34,35,36
str1 db 'PLEASE PRESS ENTER TO SELCET EACH NUMBER!',0dh,0ah,'$'
s2 ends
接着,bx是当前数组长度,刚开始时是36,bp是剩余抽奖次数,先保存好寄存器,然后调用INT 21H的7号功能,即不带回显的输入,如果是回车键,则抽奖;如果不是的话就重新输入。然后用INT 21H的2C号功能获取当前系统时间,以dl中的毫秒数作为种子,除以当前数组长度,余数作为产生的随机数,随机数作为数组下标,取出对应数组下标的元素的值保存到bx。
mov bx,36
mov bp,7
num:
push bx
mov ah,7
int 21h
cmp al,0dh
jne num
mov ah,2ch
int 21h
mov al,dl
mov ah,0
div bl
lea si,arr
mov al,ah
mov ah,0
add si,ax
mov bx,[si]
mov bh,0
mov di,si
然后把bx的值以十进制形式输出
print: xor cx,cx
mov ax,bx
mov si,10
l1: xor dx,dx
div si
push dx
inc cx
cmp ax,0
jne l1
l2: pop dx
add dl,30h
mov ah,2
int 21h
loop l2
mov dl,20h
mov ah,2
int 21h
pop bx
接着把数组长度减一并且当前数组下标的元素与当前数组随后一个元素交换,接着判断剩余抽奖次数,抽完了就直接用INT 21H的4C号功能结束程序就行了
dec bx
mov ax,[bx]
mov [di],al
dec bp
cmp bp,0
ja num
OK,分析到此结束。鉴于本人的汇编水平有限,所以以上的思路仅供参考。
完整的代码请到通过以下链接获取
完整代码
谢谢!!