- ベストアンサー
H8マイコンでアセンブラ言語を使用して乱数ルーチンを作りたい
- H8マイコンでアセンブラ言語を使用しており、乱数ルーチンの作り方について知りたい。
- 現在のメインプログラムでは、ポート4の4の状態を調べ、真ならHYOJIに分岐し、真でない場合はSTARTに戻るようになっている。
- 乱数ルーチンは現在時刻などから値を取得し、その値からランダムな値を生成する方法があるのか知りたい。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
No.1さんのおっしゃることはもっともです。 所詮、コンピュータのはじき出す乱数は疑似乱数にすぎません。 要はC言語でいうところの疑似乱数rand()が欲しいってことですよね。 疑似乱数は、システム時刻やクロックなどをシード(種)として与え、 連続して疑似乱数生成関数を呼び出すことで得るのが普通です。 Cであれば、srand()でシードを設定、rand()を順次呼び出すことで 疑似乱数が得られます。 ------------------------------------------------------------ 私は下記のようなコードで48bitの疑似乱数を発生して使いました。 ER1:ER0と連結した48ビットです。 ※H8Sのコードですので、一部書き直しが必要かもしれません 読めば分かると思うのでそのままにしておきます。 48ビットを一度に全部使うよりも最上位E1の16ビットずつ使う方が より乱数らしくなります。当たり前かもしれませんが。 シードはゼロ以外のものを与えてください。ゼロを与えると常にゼロに なってしまいます。 当然ですが、得られる乱数もゼロ以外になります。 ゼロが欲しい場合は下の方のbitを捨てて対応してください。 ------------------------------------------------------------ なお、シードが同じであれば得られる疑似乱数列は常に同じになります。 下記コードのように決め打ちでシードを与えると、疑似乱数とは言えなく なりますので、適当に変化する値をシードとして与えてください。 ★見やすくするため全角スペースを使用しています。 コピペする場合はご注意下さい。 INIT: MOV.L #H'12345678,ER0 ; シードの設定 MOV.L #H'56789ABC,ER1 ; (固定値は非推奨) MOV.L ER0,@SEED MOV.L ER1,@SEED+4 LOOP: BSR RANDOM MOV.W E1,R6 ; この時点でのER1:ER0が疑似乱数 BRA LOOP ; (E1だけを使う方がベター) RANDOM: MOV.L @SEED,ER0 MOV.L @SEED+4,ER1 MOV.W R0,E2 MOV.W E1,R2 SHAL.L #2,ER2 ; この命令の書き方はH8Sだけかも MOV.W E2,R1 MOV R1L,R1H MOV R2H,R1L XOR.W E0,R1 MOV.W R0,E0 MOV.W E1,R0 MOV.W R1,E1 MOV.L ER0,@SEED MOV.L ER1,@SEED+4 RTS .SECTION RAM,DATA,ALIGN=2 SEED: .RES.L 2
その他の回答 (1)
- MOMON12345
- ベストアンサー率32% (1125/3490)
結論から言うとランダムな数字を作る方法はありません。 必ず法則性があるからです。 だったらランダムの中の特殊な一つである「順番」でも同じじゃないかという話にもなりますね。 それでも出来るだけランダム風にしたいのであればM系列の発生器でも持ってきますか。 これも決まった順番で数値が出てくるだけですが、それらを幾つか組み合わせて途中でリセットしたりすればランダム風味になります。 しかし実は決まったとおりにしか動いてはいないのですが。
補足
回答ありがとうございます。 完璧なランダムは作らなくてよいです。 ある程度ばらつきがある数値の順番が何周も回るような程度でもよいのですが……
お礼
本題の、乱数ルーチンについてはこれで解決したと思います。コードは一部分からない点があり理解できたわけではありませんが。 擬似乱数を用いてどのように別のルーチンに分岐するか、というところでまた詰まってしまい、乱数をテストしてみるところまではいけませんでした。 しかしながらプログラムは完成に近づいていると思います。 回答ありがとうございました。