1. ホーム
  2. assembly

[解決済み] x86 8086 アセンブリで 0-9 の範囲の乱数を生成する。

2022-02-12 22:44:15

質問

まず最初に、私は8086アセンブリの初心者で、知識をつかむのがかなり困難です。でも、がんばります。

私は0-9の範囲内で乱数を生成するコードを書こうとしています。いくつかの例と提案を調べた後、これは私が最終的に得たものです。私は、取得したクロック数に数学的関数を適用しませんでした、シンプルにするため、また、私はそれが不要だと思いました。しかし、なぜか6,7は1,3,9よりも少ない回数しか生成されない。これは、数値が急激に変化する時計の低次をとっているためだと思います。

私の目的は、サイコロの目をシミュレートすることで、後で以下のコードの範囲を1-6に変更することです。 私の質問は、これは私の目的のために十分であるか、またはこれを行うには、より良い方法があるのでしょうか?

のコードを入力します。

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      
                ; lets just take the lower bits of DL for a start..
   MOV BH, 57   ; set limit to 57 (ASCII for 9) 
   MOV AH, DL  
   CMP AH, BH   ; compare with value in  DL,      
   JA RANDSTART ; if more, regenerate. if not, continue... 

   MOV BH, 49   ; set limit to 48 (ASCII FOR 0)
   MOV AH, DL   
   CMP AH, BH   ; compare with value in DL
   JB RANDSTART ; if less, regenerate.   


   ; if not, this is what we need 
   mov ah, 2h   ; call interrupt to display a value in DL
   int 21h    
RET

回答、@johnfound さんによるものです。

彼の方法の方がシンプルで、乱数生成にかかる時間が短いと感じました。この方法は、1つの乱数が必要な場合、または乱数間の間隔が人間の入力のためのポーズを含む場合にのみ有効であると述べています。そうでない場合は、乱数はまったくランダムになりません(最初に取る時間の種が変わらないためだと思います)。私の場合は、サイコロを振るシミュレーションをしているので、再びコードを実行する前にユーザーの介入(もう一回振る)が必要なので、この方法で問題ありません。

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.DXの価値をAXに移動させた。 2.DXをクリアしました。 3.CXに10decを移動しました。 4.AXをCXで割った余りを0-9 DecとしてDXに格納 5.最後にASCII '0' (dec 48) をDXに追加してASCII '0' から '9' に変換。

解決するには?

このトリックは、1つの乱数が必要な場合、または乱数間の間隔が、以下のようなポーズを含む場合にのみ機能します。 人間の入力 . それ以外の場合、数字はまったくランダムにならない。

多くの乱数が必要な場合は、さまざまな疑似乱数アルゴリズムが利用可能です。

もう一つの注意点は、必要な区間の数字をもっと簡単に求める方法があることです。

    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'

もちろん、この方法はすべての乱数発生器に使用することができます。