9

まず第一に、私は 8086 アセンブリに非常に慣れていないため、知識を得るのがかなり困難でした。それでも、頑張ります。

0 ~ 9 の範囲内で乱数を生成するコードを作成しようとしています。いくつかの例と提案を調べた後、これが最終的な結論です。簡単にするために、取得したクロック数に数学関数を適用しませんでした。また、それは不要だと思いました。何らかの理由で、1、3、9 などの数値よりも 6,7 少ない回数のような特定の数値を生成することになりました。これは、値が変化するクロックティックの下位の順序を取っているためだと思います。急速。

私の目的は、後でコードの下の範囲を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による回答:

彼の方法はより単純で、乱数を生成するのに時間がかからないことがわかりました。彼は、これは単一の乱数が必要な場合、または乱数間の間隔に人間の入力のための一時停止が含まれている場合にのみ機能すると述べました。そうでない場合、数字はまったくランダムではありません(最初に取得したタイムシードが変わらないためだと思います)。私の場合は問題ありません。なぜなら、私はロール ダイスをシミュレートしており、コードを再度実行する前にユーザーの介入 (別のロール) が必要だからです。

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.12月10日にCXに引っ越しました。4.AX を CX で割ったため、10 進数の 0 ~ 9 の剰余が得られ、DX に格納されます。 .

4

2 に答える 2

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'

もちろん、この方法はすべての乱数ジェネレーターに使用できます。

于 2013-07-25T11:10:15.693 に答える
0

この仕事のために、より小さなオペコード、AAM - Ascii Adjust for Multiplication を見つけました。このオペコードの仕組み:

AH := AL / 10
AL := AL mod 10

したがって、次のようになります。

mov al, dl
aam
add al, '0'
mov dl, al
于 2014-07-09T03:03:14.827 に答える