4

私はアセンブリ 8086emu を使用しており、8 桁の数値ジェネレータが必要です。
@johnfound によるこのコードを使用しようとしました。

RANDGEN:         ; generate a rand no using the system time

RANDSTART:
   MOV AH, 00h  ; interrupts to get system time        
   INT 1AH      ; CX:DX now hold number of clock ticks since midnight      

   mov  ax, dx
   xor  dx, dx
   mov  cx, 10    
   div  cx       ; here dx contains the remainder of the division - from 0 to 9

   add  dl, '0'  ; to ascii from '0' to '9'
   mov ah, 2h   ; call interrupt to display a value in DL
   int 21h    
RET    

ただし、1 つの数値を生成する場合にのみ役立ちます。そのクロックは 1 秒間に 18.2 回しか時を刻まないため、繰り返し呼び出しても同じ番号が返されます。

疑似乱数関数を作成しようとしましたが、アセンブリが初めてで、成功しませんでした。Math.random()emu8086 でJava の機能に似たようなことをする方法があれば知りたいです。

4

2 に答える 2

7

単純な疑似乱数ジェネレーターの 1 つは、現在の数値に 25173 を掛けてから、それに 13849 を加算します。この値が新しい乱数になります。
あなたのようにシステム タイマーから開始した場合 (これは、乱数ジェネレーターのシードと呼ばれます)、この一連の数値は、単純なタスクに対して十分にランダムになります!

MOV     AH, 00h   ; interrupt to get system timer in CX:DX 
INT     1AH
mov     [PRN], dx
call    CalcNew   ; -> AX is a random number
xor     dx, dx
mov     cx, 10    
div     cx        ; here dx contains the remainder - from 0 to 9
add     dl, '0'   ; to ascii from '0' to '9'
mov     ah, 02h   ; call interrupt to display a value in DL
int     21h    
call    CalcNew   ; -> AX is another random number
...
ret

; ----------------
; inputs: none  (modifies PRN seed variable)
; clobbers: DX.  returns: AX = next random number
CalcNew:
    mov     ax, 25173          ; LCG Multiplier
    mul     word ptr [PRN]     ; DX:AX = LCG multiplier * seed
    add     ax, 13849          ; Add LCG increment value
    ; Modulo 65536, AX = (multiplier*seed+increment) mod 65536
    mov     [PRN], ax          ; Update seed = return value
    ret

これは、2 の累乗法で線形合同ジェネレーター (LCG) を実装します。 %65536積 + インクリメントの下位 16 ビットは AX にあり、上位ビットはそうではないため、無料で発生します。

于 2016-11-20T21:36:12.493 に答える