[请教高手]单片机怎么实现产生随机数?

汇编里面没有这种指令,我想可以从计时器中取数来实现,但不知怎么做,请教~

24 浏览 2 回复
  种子   db   sta   temp   lda  

回复

    给你一个超强例子:
    欢迎到卡卡空间:<http://hi.baidu.com/woodking>主 题: 线性叠加伪随机数函数
    ; 关 键 词: 随机数,8位单片机,random,8 bit mcu
    ; 参考资料: 1.<<Linear Congruential Pseudo-Random Number Generator Routines>>
    ; by Bruce Clark, 7 Jun 2004
    ; 2.<<The Art Of Computer Programming, Volume 2>>
    ; by Donald Knuth
    ;
    8位单片机很多地方需要随机数,比如游戏的洗牌,可在timer中取数,但是随机数质
    量不高。随机数是一个既简单又复杂的问题,这里的例子使用了众所周知的线性叠加法,没
    有完美的方法产生随机数,不过线性叠加法是一个合适的方法,彻底解决8位机随机数的问
    题。
    伪随机数函数总是返回可预知的数字,像抛骰子,如果抛足够多次,那么我们得到了一
    个足够长的数字序列,
    3,1,5,1,4,6,5,4,6,5,4,5,6,1,3,2,1,6,4,6,5,4,3,2,1,3,2,1,4,2,3,1,3......
    如果从序列中一个接一个的取出数字,那么数字就看似随机。
    问题的关键是从这序列的哪个点(数字)开始取数?这个开始的点(数字)叫做种子。
    注意,如果从相同的点(种子)开始,将会得到相同的数字,这是因为我们是从固定的序
    列中取数字(所以叫伪随机)。但这却是一个有用的特性,我们可以每次从不同的点取数,即
    改变种子!
    在6502上,8位或16位随机数是最常用的,函数返回一个32位的数字,范围0~2^32。名
    词"线性叠加"听起来容易范晕, 其实只涉及二个内容:乘法和加法。三个步骤:
    1. 为了取得新的种子(也就是从序列开始的那个点的数字),旧的种子和一个常数A相乘,
    2. 所得结果然后和第二个常数c相加。
    3. 新的种子是结果的低32位(记住,这个函数返回32位数字)。保留低32位很重要,用来获
    得下一个种子。
    计算公式:
    种子 = A * 种子 + C
    此公式在几何图中表示一条直线,而且新种子由旧种子反复相加得来,所以叫线性叠加。
    随机数函数的关键在于选择优秀的"常数A"(也叫乘数A),其实也就是选择了一个固定
    的数字序列。"常数c",不像乘数A那样重要,但是它一定是个奇数。事实上, c可选1,而
    且这是例程所使用的,因为它会简化计算。
    注意,奇数(旧的种子)乘奇数(乘数A)是奇数,再加奇数(常数c)将会是一个偶数;偶数
    (旧的种子)乘奇数(乘数A),加奇数(常数c)将会是一个奇数。如此种子将会在奇数和偶数之
    间转变。因为种子的变化足够随机,所以新种子的值可以作为8位或16位随机数。
    子程序F_RandomSeed,计算 "种子 = 乘数 * 种子+1" (记得,c=1)。有三个版本:
    (1) 快速版本, 速度快,但占用Rom多。
    (2) 兼顾版本,速度和占用Rom适中,空间和速度是在另外二个版本之间。
    兼顾版B, 使用了另一个神奇的数字66066(10进制).
    (3) 最小版本,速度慢,但占用Rom小。
    三个版本中使用的乘数1664525(10进制)=19660D(16进制),是从<<计算机程序的艺术,
    第2册>>一书中选出,这是一个神奇的数字,经过论证和测试,这个数字对产生随机数至
    关重要。想进一步研究的朋友可以阅读原著(参考资料2),书中以特别专业的数学方法讨论
    了随机数问题。这里只是应用了其中的两个常数1664525(10进制)和69069(10进制),这里不
    作讨论,因为篇幅问题是借口,其实自己没弄懂。
    ;==============================================================================
    ; 快速版本
    ;==============================================================================
    丰收先要选好种子,育种很重要,同样,获得随机种子是重要的一步。
    种子变量设定在零页RAM可以提高速度。
    程序F_RandomSeed计算 1664525*种子,需要5个字节(R_Seed0~R_Seed3,R_Temp)。
    F_GeneratTables预先计算1664525*X(x=0~255),生成四个256字节的列表T3,T2,T1,T0.
    T3,X = 表T3的第X字节 = 1664525 * X的第31~24位(X = 0 to 255)
    T2,X = 表T2的第X字节 = 1664525 * X的第23~16位(X = 0 to 255)
    T1,X = 表T1的第X字节 = 1664525 * X的第15~ 8位(X = 0 to 255)
    T0,X = 表T0的第X字节 = 1664525 * X的第 7~ 0位(X = 0 to 255)
    对于单片机来说 使用1K RAM很夸张,也可以不用F_GeneratTables,直接把随机数表存
    在ROM中。
    ;==============================================================================
    ; 伪随机数函数的线性叠加
    ; 计算 Seed = 1664525 * Seed + 1
    ;------------------------------------------------------------------------------
    ; 输入:
    ; R_Seed0 <--- 种子0
    ; R_Seed1 <--- 种子1
    ; R_Seed2 <--- 种子2
    ; R_Seed3 <--- 种子3
    ; 回返:
    ; 种子0 ---> R_Seed0
    ; 种子1 ---> R_Seed1
    ; 种子2 ---> R_Seed2
    ; 种子3 ---> R_Seed3
    ; 重写
    ; R_Temp
    ;------------------------------------------------------------------------------
    ; 为提高速度R_Seed0,R_Seed1,R_Seed2,R_Seed3,R_Temp选零页Ram
    ; 每张列表从Rom地址 xx00h 处开始 或在Rom中
    ;------------------------------------------------------------------------------
    ; 空间: 程序58个字节
    ; 列表1024个字节
    ; 速度: 调用F_RandomSeed需要94个周期
    ;==============================================================================
    F_RandomSeed:
    CLC ; 计算低32位:
    LDX R_Seed0 ; 1664525*($100* R_Seed1+ R_Seed0)+1
    LDY R_Seed1
    LDA T0,X
    ADC #1
    STA R_Seed0
    LDA T1,X
    ADC T0,Y
    STA R_Seed1
    LDA T2,X
    ADC T1,Y
    STA R_Temp
    LDA T3,X
    ADC T2,Y
    TAY ; 把字节3留在Y中
    CLC ; 加低32位:
    LDX R_Seed2 ; 1664525*($10000* R_Seed2)
    LDA R_Temp
    ADC T0,X
    STA R_Seed2
    TYA
    ADC T1,X
    CLC
    LDX R_Seed3 ; 加低32位:
    ADC T0,X ; 1664525*($1000000* R_Seed3)
    STA R_Seed3
    rts
    ;==============================================================================
    ; 产生T0,T1,T2和T3列表,使用F_GeneratTables,列表在ram中
    ;==============================================================================
    F_GeneratTables:
    LDX #0 ;1664525*0=0
    STX T0
    STX T1
    STX T2
    STX T3
    INX
    CLC
    L_GT1:
    LDA T0-1,X ;把1664525加入
    ADC #$0D ;字节0
    STA T0,X
    LDA T1-1,X
    ADC #$66 ;字节1
    STA T1,X
    LDA T2-1,X
    ADC #$19 ;字节2
    STA T2,X
    LDA T3-1,X
    ADC #$00 ;字节3
    STA T3,X
    INX ;进位C=0退出
    BNE L_GT1
    RTS
    ;------------------------------------------------------------------------------
    ; 生成的列表,如果不要F_GeneratTables,可以直接将此表放在Rom中
    ;------------------------------------------------------------------------------
    ;1664525 * X的第31~24位(X = 0 to 255)
    T3:
    .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01,$01,$01,$01,$01
    .DB $01,$01,$01,$01,$01,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$03
    .DB $03,$03,$03,$03,$03,$03,$03,$03,$03,$04,$04,$04,$04,$04,$04,$04
    .DB $04,$04,$04,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$06,$06,$06
    .DB $06,$06,$06,$06,$06,$06,$06,$07,$07,$07,$07,$07,$07,$07,$07,$07
    .DB $07,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$09,$09,$09,$09,$09
    .DB $09,$09,$09,$09,$09,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0B
    .DB $0B,$0B,$0B,$0B,$0B,$0B,$0B,$0B,$0B,$0C,$0C,$0C,$0C,$0C,$0C,$0C
    .DB $0C,$0C,$0C,$0C,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0E,$0E
    .DB $0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F
    .DB $0F,$0F,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$11,$11,$11,$11
    .DB $11,$11,$11,$11,$11,$11,$12,$12,$12,$12,$12,$12,$12,$12,$12,$12
    .DB $13,$13,$13,$13,$13,$13,$13,$13,$13,$13,$14,$14,$14,$14,$14,$14
    .DB $14,$14,$14,$14,$15,$15,$15,$15,$15,$15,$15,$15,$15,$15,$16,$16
    .DB $16,$16,$16,$16,$16,$16,$16,$16,$17,$17,$17,$17,$17,$17,$17,$17
    .DB $17,$17,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$19,$19,$19,$19
    ;1664525 * X的第23~16位(X = 0 to 255)
    T2:
    .DB $00,$19,$32,$4C,$65,$7E,$98,$B1,$CB,$E4,$FD,$17,$30,$4A,$63,$7C
    .DB $96,$AF,$C9,$E2,$FB,$15,$2E,$48,$61,$7A,$94,$AD,$C7,$E0,$F9,$13
    .DB $2C,$46,$5F,$78,$92,$AB,$C5,$DE,$F7,$11,$2A,$44,$5D,$76,$90,$A9
    .DB $C3,$DC,$F5,$0F,$28,$42,$5B,$74,$8E,$A7,$C1,$DA,$F3,$0D,$26,$40
    .DB $59,$72,$8C,$A5,$BF,$D8,$F1,$0B,$24,$3E,$57,$70,$8A,$A3,$BD,$D6
    .DB $EF,$09,$22,$3C,$55,$6E,$88,$A1,$BB,$D4,$ED,$07,$20,$3A,$53,$6C
    .DB $86,$9F,$B9,$D2,$EB,$05,$1E,$38,$51,$6A,$84,$9D,$B7,$D0,$E9,$03
    .DB $1C,$36,$4F,$68,$82,$9B,$B5,$CE,$E7,$01,$1A,$34,$4D,$66,$80,$99
    .DB $B3,$CC,$E5,$FF,$18,$32,$4B,$64,$7E,$97,$B1,$CA,$E3,$FD,$16,$30
    .DB $49,$62,$7C,$95,$AE,$C8,$E1,$FB,$14,$2D,$47,$60,$7A,$93,$AC,$C6
    .DB $DF,$F9,$12,$2B,$45,$5E,$78,$91,$AA,$C4,$DD,$F7,$10,$29,$43,$5C
    .DB $76,$8F,$A8,$C2,$DB,$F5,$0E,$27,$41,$5A,$74,$8D,$A6,$C0,$D9,$F3
    .DB $0C,$25,$3F,$58,$72,$8B,$A4,$BE,$D7,$F1,$0A,$23,$3D,$56,$70,$89
    .DB $A2,$BC,$D5,$EF,$08,$21,$3B,$54,$6E,$87,$A0,$BA,$D3,$ED,$06,$1F
    .DB $39,$52,$6C,$85,$9E,$B8,$D1,$EB,$04,$1D,$37,$50,$6A,$83,$9C,$B6
    .DB $CF,$E9,$02,$1B,$35,$4E,$68,$81,$9A,$B4,$CD,$E7,$00,$19,$33,$4C
    ;1664525 * X的第15~ 8位(X = 0 to 255)
    T1:
    .DB $00,$66,$CC,$32,$98,$FE,$64,$CA,$30,$96,$FC,$62,$C8,$2E,$94,$FA
    .DB $60,$C6,$2C,$92,$F9,$5F,$C5,$2B,$91,$F7,$5D,$C3,$29,$8F,$F5,$5B
    .DB $C1,$27,$8D,$F3,$59,$BF,$25,$8B,$F2,$58,$BE,$24,$8A,$F0,$56,$BC
    .DB $22,$88,$EE,$54,$BA,$20,$86,$EC,$52,$B8,$1E,$84,$EB,$51,$B7,$1D
    .DB $83,$E9,$4F,$B5,$1B,$81,$E7,$4D,$B3,$19,$7F,$E5,$4B,$B1,$17,$7E
    .DB $E4,$4A,$B0,$16,$7C,$E2,$48,$AE,$14,$7A,$E0,$46,$AC,$12,$78,$DE
    .DB $44,$AA,$10,$77,$DD,$43,$A9,$0F,$75,$DB,$41,$A7,$0D,$73,$D9,$3F
    .DB $A5,$0B,$71,$D7,$3D,$A3,$09,$70,$D6,$3C,$A2,$08,$6E,$D4,$3A,$A0
    .DB $06,$6C,$D2,$38,$9E,$04,$6A,$D0,$36,$9C,$03,$69,$CF,$35,$9B,$01
    .DB $67,$CD,$33,$99,$FF,$65,$CB,$31,$97,$FD,$63,$C9,$2F,$95,$FC,$62
    .DB $C8,$2E,$94,$FA,$60,$C6,$2C,$92,$F8,$5E,$C4,$2A,$90,$F6,$5C,$C2
    .DB $28,$8E,$F5,$5B,$C1,$27,$8D,$F3,$59,$BF,$25,$8B,$F1,$57,$BD,$23
    .DB $89,$EF,$55,$BB,$21,$88,$EE,$54,$BA,$20,$86,$EC,$52,$B8,$1E,$84
    .DB $EA,$50,$B6,$1C,$82,$E8,$4E,$B4,$1A,$81,$E7,$4D,$B3,$19,$7F,$E5
    .DB $4B,$B1,$17,$7D,$E3,$49,$AF,$15,$7B,$E1,$47,$AD,$13,$7A,$E0,$46
    .DB $AC,$12,$78,$DE,$44,$AA,$10,$76,$DC,$42,$A8,$0E,$74,$DA,$40,$A6
    ;1664525 * X的第 7~ 0位(X = 0 to 255)
    T0:
    .DB $00,$0D,$1A,$27,$34,$41,$4E,$5B,$68,$75,$82,$8F,$9C,$A9,$B6,$C3
    .DB $D0,$DD,$EA,$F7,$04,$11,$1E,$2B,$38,$45,$52,$5F,$6C,$79,$86,$93
    .DB $A0,$AD,$BA,$C7,$D4,$E1,$EE,$FB,$08,$15,$22,$2F,$3C,$49,$56,$63
    .DB $70,$7D,$8A,$97,$A4,$B1,$BE,$CB,$D8,$E5,$F2,$FF,$0C,$19,$26,$33
    .DB $40,$4D,$5A,$67,$74,$81,$8E,$9B,$A8,$B5,$C2,$CF,$DC,$E9,$F6,$03
    .DB $10,$1D,$2A,$37,$44,$51,$5E,$6B,$78,$85,$92,$9F,$AC,$B9,$C6,$D3
    .DB $E0,$ED,$FA,$07,$14,$21,$2E,$3B,$48,$55,$62,$6F,$7C,$89,$96,$A3
    .DB $B0,$BD,$CA,$D7,$E4,$F1,$FE,$0B,$18,$25,$32,$3F,$4C,$59,$66,$73
    .DB $80,$8D,$9A,$A7,$B4,$C1,$CE,$DB,$E8,$F5,$02,$0F,$1C,$29,$36,$43
    .DB $50,$5D,$6A,$77,$84,$91,$9E,$AB,$B8,$C5,$D2,$DF,$EC,$F9,$06,$13
    .DB $20,$2D,$3A,$47,$54,$61,$6E,$7B,$88,$95,$A2,$AF,$BC,$C9,$D6,$E3
    .DB $F0,$FD,$0A,$17,$24,$31,$3E,$4B,$58,$65,$72,$7F,$8C,$99,$A6,$B3
    .DB $C0,$CD,$DA,$E7,$F4,$01,$0E,$1B,$28,$35,$42,$4F,$5C,$69,$76,$83
    .DB $90,$9D,$AA,$B7,$C4,$D1,$DE,$EB,$F8,$05,$12,$1F,$2C,$39,$46,$53
    .DB $60,$6D,$7A,$87,$94,$A1,$AE,$BB,$C8,$D5,$E2,$EF,$FC,$09,$16,$23
    .DB $30,$3D,$4A,$57,$64,$71,$7E,$8B,$98,$A5,$B2,$BF,$CC,$D9,$E6,$F3
    ;==============================================================================
    ; 最小版本
    ;==============================================================================
    对于单片机来说,使用1K RAM或rom来完成一个随机数,是很浪费的,以下是最小版本,
    但是程序执行周期长。程序每次计算所需要的列表值。
    ;==============================================================================
    ; 线性叠加伪随机数函数
    ; 计算 R_Seed=1664525 * R_Seed + 1
    ;------------------------------------------------------------------------------
    ; 输入:
    ; R_Seed0 <--- 种子0
    ; R_Seed1 <--- 种子1
    ; R_Seed2 <--- 种子2
    ; R_Seed3 <--- 种子3
    ; 回返:
    ; 种子0 ---> R_Seed0
    ; 种子1 ---> R_Seed1
    ; 种子2 ---> R_Seed2
    ; 种子3 ---> R_Seed3
    ; 重写
    ; R_Temp,R_Temp+1,R_Temp+2,R_Temp+3
    ; 注意
    ; R_Temp~R_Temp+3 和 L_Rand6 是高字节在前,低字节在后
    ;------------------------------------------------------------------------------
    ; 空间: 53个字节
    ; 速度: 调用F_RandomSeed平均2744个周期
    ; 1624+70* N(N=种子数) = 1624~3864个周期
    ;==============================================================================
    F_RandomSeed:
    LDA #1 ; R_Temp=1,需要给定初始值
    LDX #3
    L_Rand1 STA R_Temp,X
    LSR
    DEX
    BPL L_Rand1
    LDY #$20 ; 计算种子 = 种子 * L_Rand4+ R_Temp
    BNE L_Rand5 ; 总是分支
    L_Rand2 BCC L_Rand4 ; 如果零被移位,分支
    CLC ; 把乘数加入乘积
    LDX #3
    L_Rand3 LDA R_Temp,X
    ADC T_Rand6,X ;源码有误,已改正
    STA R_Temp,X
    DEX
    BPL L_Rand3
    L_Rand4 ROR R_Temp ; 右移结果
    ROR R_Temp+1
    ROR R_Temp+2
    ROR R_Temp+3
    L_Rand5 ROR R_Seed3 ; 右移种子
    ROR R_Seed2
    ROR R_Seed1
    ROR R_Seed0
    DEY
    BPL L_Rand2
    RTS
    T_Rand6 .DB $00,$19,$66,$0D ;乘数(高字节在前)
    ;==============================================================================
    ; 兼顾版本 乘数1664525(10进制)
    ;==============================================================================
    兼顾版本 是不用上面的循环加来做乘法,而是在必要的时候加上 种子,$100* 种子,
    $10000* 种子,来获得数字序列,这样能够提高速度,又不增加太多代码。
    分解公式表
    b7 b6 b5 b4 b3 b2 b1 b0
    $0D = 0 0 0 0 1 1 0 1 b ---> +种子
    $66 = 0 1 1 0 0 1 1 0 b ---> *$100h
    $19 = 0 0 0 1 1 0 0 1 b ---> *$10000h
    $00 = 0 0 0 0 0 0 0 0 b --->
    | | | | | | | |
    | | | | | | | |
    V V V V V V V V
    左 左 左 左 左 左
    移 移 移 移 移 移
    6 5 4 3 2 1
    位 位 位 位 位 位
    那么 种子*bit0 时,种子*$10000+种子
    种子*bit1 时,种子*$100, 左移1位
    种子*bit2 时,种子*$100+种子, 左移2位
    种子*bit3 时,种子*$10000+种子,左移3位
    种子*bit4 时,种子*$10000, 左移4位
    种子*bit5 时,种子*$100, 左移5位
    种子*bit6 时,种子*$100, 左移6位
    ;==============================================================================
    ; 伪随机数函数的线性叠加
    ; 计算 R_Seed=1664525 * R_Seed + 1
    ;------------------------------------------------------------------------------
    ; 输入:
    ; R_Seed0 <--- 种子0
    ; R_Seed1 <--- 种子1
    ; R_Seed2 <--- 种子2
    ; R_Seed3 <--- 种子3
    ; 回返:
    ; 种子0 ---> R_Seed0
    ; 种子1 ---> R_Seed1
    ; 种子2 ---> R_Seed2
    ; 种子3 ---> R_Seed3
    ; 重写
    ; R_Temp,R_Temp+1,R_Temp+2,R_Temp+3
    ;-------------------------------------------------------------------------------
    ; 空间: 106个字节
    ; 速度: F_RandomSeed 517个周期
    ;===============================================================================
    F_RandomSeed:
    CLC ; 复制种子进入R_Temp
    LDA R_Seed0 ; 计算 种子 = 种子 *$10000+ 种子 +1
    STA R_Temp
    ADC #1
    STA R_Seed0
    LDA R_Seed1
    STA R_Temp+1
    ADC #0
    STA R_Seed1
    LDA R_Seed2
    STA R_Temp+2
    ADC R_Temp
    STA R_Seed2
    LDA R_Seed3
    STA R_Temp+3
    ADC R_Temp+1
    STA R_Seed3
    ;-------------------------------------------------
    ;因为$0019660D 的Bit7=0,所以只需6次移位
    ;-------------------------------------------------
    LDY #5
    L_Rand1 ASL R_Temp ; 左移旧的种子
    ROL R_Temp+1
    ROL R_Temp+2
    ROL R_Temp+3
    ;-------------------------------------------------
    ; 从 L_Rand4 列表取得 X, 4个索引值对应4种情况,数值选的巧妙!
    ; X=$00, 种子 = 种子 +$10000* R_Temp
    ; X=$01, 种子 = 种子 +$100 * R_Temp
    ; X=$FE, 种子 = 种子 +$10000* R_Temp+ R_Temp
    ; X=$FF, 种子 = 种子 +$100 * R_Temp+ R_Temp
    ;-------------------------------------------------
    LDX L_Rand4,Y
    BPL L_Rand2 ; 分支如果 X=$00 或 X=$01
    CLC ; 种子 = 种子 +R_Temp
    LDA R_Seed0
    ADC R_Temp
    STA R_Seed0
    LDA R_Seed1
    ADC R_Temp+1
    STA R_Seed1
    LDA R_Seed2
    ADC R_Temp+2
    STA R_Seed2
    LDA R_Seed3
    ADC R_Temp+3
    STA R_Seed3
    INX ; $ FE->$00,$ FF->$01
    INX
    L_Rand2 CLC
    BEQ L_Rand3 ; 如果 X=$00, 种子 =种子 + R_Temp*$10000
    LDA R_Seed1 ; 种子 = 种子 + R_Temp*$100
    ADC R_Temp
    STA R_Seed1
    L_Rand3 LDA R_Seed2
    ADC R_Temp,X
    STA R_Seed2
    LDA R_Seed3
    ADC R_Temp+1,X
    STA R_Seed3
    DEY
    BPL L_Rand1
    RTS
    L_Rand4 .DB $01,$01,$00,$FE,$FF,$01
    ;==============================================================================
    ; 改进的 兼顾版本B 选择新的 乘数=69069(10进制)
    ;==============================================================================
    兼顾版本B中, 用69069(10进制)替换1664525(10进制)作乘数,也就是说,选择了另外一
    个数字序列,这个乘数也是<<计算机程序的艺术,第2册>>一书中选出,经过论证和测试,
    这个数字虽不及1664525做乘数好,但也是个神奇的数字,而且可以进一步减小程序时间。
    ;===============================================================================
    ; 伪随机数函数的线性叠加
    ; 计算种子 = 种子 * 69069 + 1
    ;-------------------------------------------------------------------------------
    ; 输入:
    ; R_Seed0 <--- 种子0
    ; R_Seed1 <--- 种子1
    ; R_Seed2 <--- 种子2
    ; R_Seed3 <--- 种子3
    ; 回返:
    ; 种子0 ---> R_Seed0
    ; 种子1 ---> R_Seed1
    ; 种子2 ---> R_Seed2
    ; 种子3 ---> R_Seed3
    ; 重写
    ; R_Temp,R_Temp+1,R_Temp+2,R_Temp+3
    ;--------------------------------------------------------------------------------
    ; 空间: 173个字节
    ; 速度: F_RandomSeed 326个周期
    ;================================================================================
    F_RandomSeed:
    LDA R_Seed0 ; R_Temp= 种子 *2
    ASL
    STA R_Temp
    LDA R_Seed1
    ROL
    STA R_Temp+1
    LDA R_Seed2
    ROL
    STA R_Temp+2
    LDA R_Seed3
    ROL
    STA R_Temp+3
    CLC ; R_Temp= R_Temp+ 种子 (= 种子 *3)
    LDA R_Seed0
    ADC R_Temp
    STA R_Temp
    LDA R_Seed1
    ADC R_Temp+1
    STA R_Temp+1
    LDA R_Seed2
    ADC R_Temp+2
    STA R_Temp+2
    LDA R_Seed3
    ADC R_Temp+3
    STA R_Temp+3
    CLC ; 种子 = 种子 +$10000* 种子
    LDA R_Seed2
    ADC R_Seed0
    TAX ; 把字节2保存在X中(利于提高速度)
    LDA R_Seed3
    ADC R_Seed1
    TAY ; 把字节3保存在Y中
    CLC ; 种子 = 种子 +$100* 种子
    LDA R_Seed1
    ADC R_Seed0
    PHA ; 压入堆栈字节1
    TXA
    ADC R_Seed1
    TAX
    TYA
    ADC R_Seed2
    TAY
    LDA R_Temp ; R_Temp= R_Temp*4(= 旧种子 *$0C)
    ASL
    ROL R_Temp+1
    ROL R_Temp+2
    ROL R_Temp+3
    ASL
    ROL R_Temp+1
    ROL R_Temp+2
    ROL R_Temp+3
    STA R_Temp
    CLC ; 种子 = 种子 +R_Temp
    ADC R_Seed0
    STA R_Seed0
    PLA ; 弹出堆栈的字节1
    ADC R_Temp+1
    STA R_Seed1
    TXA
    ADC R_Temp+2
    TAX
    TYA
    ADC R_Temp+3
    TAY
    CLC
    LDA R_Temp ; 种子 = 种子 + R_Temp*$100
    ADC R_Seed1
    STA R_Seed1导入 在此 参考资料end 参考资料

    郭倰

    给你例子,看有用的不?
    Random Number Generator
    In this application program, random numbers are generated by the system timer.
    Generating four random numbers
    ;************************************************************************
    ;File name: RANDOM1.ASM
    ;Input Arguments: TM0,T0L,T0H
    ;Output Arguments: RAN0,RAN1,RAN2,RAN3
    ;*************************************************************************
    ;System register table define
    ;**************************
    INT EQU 00H
    IRQ EQU 01H
    TM0 EQU 02H
    T0L EQU 04H
    T0H EQU 05H
    ;**************************
    ;RAM REGISTER TABLE
    ;**************************
    RAN0 EQU 20H ;random 0 register
    RAN1 EQU 21H ;random 1 register
    RAN2 EQU 22H ;random 2 register
    RAN3 EQU 23H ;random 3 register
    CNT1 EQU 24H ;variable register
    CNT2 EQU 25H ;variable register
    ;**************************
    ORG 00H
    JMP RESET
    NOP
    JMP TIMER0 ;timer 0 interrupt
    NOP
    NOP
    ;**************************
    RESET:
    LDI TM0,0101B ;set timer 0 freq.
    LDI T0L,00H ;clear TOL
    LDI T0H,00H ;clear TOH
    LDI INT,04H ;enable timer 0 interrupt
    LDI IRQ,00H ;clear interrupt flag
    CALL RANDOM ;call get random sub_program
    JMP $-1
    ;**************************
    ;TIMER 0 INTERRUPT SUB PROGRAM
    ;**************************
    TIMER0
    LDI INX,04H ;enable timer 0 interrupt
    LDI IRQ,00H ;clear interrupt request flag
    RTNI
    ;**************************
    ;GET FOUR RANDOM NUMBER
    ;**************************
    RANDOM
    CALL DELAY ;call delay time program
    LDA T0H,00H ;read timer 0 high nibble number
    STA RAN0,00H ;save to RAN0
    82/126 Ver1.0
    LDA T0L,00H ;read timer 0 low nibble number
    STA RAN1,00H ;save to RAM1
    CALL DELAY ;call delay time program
    LDA T0H,00H ;read timer 0 high nibble number
    STA RAN2,00H ;save to RAN2
    LDA T0L,00H ;read timer 0 low nibble number
    STA RAN3,00H ;save to RAM3
    LDA RAN0,00H ;get random data
    STA T0L,00H ;initial TOL
    LDA RAN3,00H ;get random data
    STA T0H,00H ;initial TOH
    RTNI
    ;****************************
    ;DELAY FOR A LONG TIME
    ;****************************
    DELAY ;
    LDI CNT1,0AH
    LDI CNT2,0FH
    SBIM CNT2,01H
    BC $-1
    SBIM CNT1,01H
    BC $-4
    RTNI
    这个是用四位机写的程序,看看有没有用?

    闫超

相关信息

DB DW DD简单问题

F DB 3 DUP (1,2,DUP(0));9个数顺序为:1,0,0,1,0,0,1,0,0 G DW ′AB′,′CD′;按BADC的ASCII顺序存放,即42H,41H,44H,43H & 0FABH ;&续行标志,FABH一个字 L DB 5 DUP (′Hello′,0DH,0AH);分配35个字节值为Hello〈CR〉〈CF〉重复5次 分析过程~~~~谢谢

1 浏览 1 回复   字节   重复   dup   db   数据  

哪种模式使用STA / MTA

<p>我试图创建COM组件,它会经常用Excel应用程序调用(Excel将加载COM在它的初始化),而另一进程(比方说PROCA)也传送(高频)窗口消息这个组件。目前,我实现COM为STA,不过,我经历了,虽然COM是忙于处理来自PROCA处理邮件,Excel的用户界面会被卡住。 P&gt; </p><p>请帮我解决这个问题。我可以只创建一个简单的窗口线...

1 浏览 1 回复   线程   gt   组件   com   excel  

OTP S / KEY - 如何种子产生,它们是随机的,每次?

<p>我期待在开发一次性口令认证系统(J2ME的手机,PHP的服务器端) P&gt; </p><p>我试图让我的头周围的过程中,这里是我的理解 P&gt; </p><ol> <li>用户&gt;输入随机的秘密(S)到次哈希数n li&gt; </li><li>用户&...

21 浏览 1 回复   gt   种子   服务器   服务   务器  

NASM和有关ADC的问题 - ASM 8086

<p>我在高中学习组装,我想尝试在家里做汇编程序。结果 我下载NASM,但我不明白如何与它运行.S文件 - 如果你可以写一个简单的方法,在这里运行它我倒是很高兴: - ) P&gt; </p><p>和另外我有一个问题:当我使用ADC为〔实施例:AL = 01和BL = 02和CF = 1,当我提出这一点: ADC AL,BL 将AL是3或4? (使用CF...

3 浏览 1 回复   gt   使用   nasm   adc   问题  

vb 随机函数格式

如题!

11 浏览 6 回复   随机   rnd   随机数   机数   生成