;线性同余产生随机数
assume cs:code
;数据临时缓冲
buffer segment
db 16 dup(0)
buffer ends
code segment
start:
mov dx , 0 ;
mov ax , 3 ;参数Xn[参数:随机序列中数值的下限]
mov di , 160 ;控制显示位置
mov cx , 180 ;产生伪随机数的个数
rand:
push cx
mov bx , 17 ;参数a)[参数:影响每次随机数的值](不能为1,否则将是一个线性序列
mov cx , 2998 ;参数c [参数:影响每次随机数的值]
call countDiv ;计算被除数,即aXn + c
mov cx , 32767 ;参数m[参数:随机序列中数值的上限,并影响随机序列的周期长度]
call getAC ;得到一个伪随机序列的一个值,即一个随机数
push ax
call divsub
mov bx , di
call view ;显示产生的随机数
add di , 20
pop ax
pop cx
loop rand
mov ah , 07H ;任意键退出
int 21H
mov ax , 4C00H
int 21h
;===================================
;Xn+1 = (aXn + c)%m 中的 aXn+c
;参数dx:Xn高16位;ax:Xn低16位;bx:a ;cx:c , 返回值 dx高位,ax低位
countDiv:
push bx
push cx
push si
push di
mul bx
sub si , si ;置cf标志位为0
add ax , cx
adc dx , 0
pop di
pop si
pop cx
pop bx
ret
;==================================
;求X % m ,余数就是随机序列中的值
;参数dx:X的高16位;ax:X的低16位;cx:m
;返回值放在ax中,16位除法,所得余数必然小于FFFFH
getAC:
push bx
push di
push si
;mov cx , 32767 ;[测试]
mov bx , ax ;保存ax
mov ax , dx
mov dx , 0
div cx ;除数16位,被除数在dx:ax中,余数放dx,商放在ax
mov ax , bx
div cx
mov ax , dx ;最后的余数即随机数放在ax
mov dx , 0
pop si
pop di
pop bx
ret
;================================================
;将一个多位数转化成一个个数字,同时解决不溢出的除法
;ax数据低16位,dx数据高16位,si记录分析出来的字符的个数
divsub:
push ds
push bx
push cx
push dx
push di
mov di , 0AH ;除数为10
mov bx , buffer
mov ds , bx
mov si , 0 ;si为记录数据个数的,用来向缓冲去输入数据是寻址
go:
cmp dx , 0H
je next
goon:
push ax
mov ax , dx
mov dx , 0
div di ;商在ax,余数在dx
mov cx , ax ;把商先保存
pop ax
div di
mov byte ptr ds:[si] , dl ;余数放到数据缓冲区
add si , 1
mov dx , cx
jmp go
next:
cmp ax , 0H
jne goon
cmp si , 0H
jne divRet
mov byte ptr ds:[si] , 0H
add si , 1
divRet:
pop di
pop dx
pop cx
pop bx
pop ds
ret
;===============================================
;显示数据,bx控制显示位置
view:
push ds
push es
push ax
push cx
push si
push di
mov ax , 0B800H
mov es , ax
mov ax , buffer
mov ds , ax
mov di , 20 ;为了数字右对齐
mov cx , si
mov si , 0
nextChar:
mov al , ds:[si]
add al , 30H
sub di , 1
mov byte ptr es:[bx+di] , 0AH
sub di , 1
mov es:[bx+di] , al
add si , 1H
loop nextChar
pop di
pop si
pop cx
pop ax
pop es
pop ds
ret
code ends
end start
[07/09/21] |