d get, set によるデバッグ

MN-Core エミュレータには、各種メモリの内容を表示したり、値を設定したりするための制御命令が用意されています。

提出の際にこれらの行は取り除かれ、行数としてはカウントされませんが、コードテストなどでは使用することができます。

詳しい使い方は

を御覧ください。

d get : 値を取得する

コードテストで Testcase として Plus 2 を選択し、以下の VSM を実行してみてください。

d getd $lm4n0c0b0m0p0 1 d getd $lm6n0c0b0m0p0 1

Standard Error をスクロールするか、D-GET ボタンを押すと、以下のような行が見つかると思います。

------------------- user dump -------------------- DEBUG-LM0(n0c0b0m0p0,4):(0) (0x0000000000000019) #d getd $lm4n0c0b0m0p0 1 DEBUG-LM0(n0c0b0m0p0,6):(0) (0x000000000000003d) #d getd $lm6n0c0b0m0p0 1

d get 命令はエミュレータ専用のダンプ命令です。MN-Core 2 の実機で使うことはできませんが、エミュレータで実行する際のデバッグに使えます。

d get 文のフォーマットとしては

d getd $lm4n0c0b0m0p0 1 ^ d d:double, f:float, h:half ^^^^ $lm4 どのメモリ・語長か ^^^^^^^^^^ n0c0b0m0p0 どこの PE か。この例では group=0(n0), l2bid=0 (c0), l1bid=0 (b0), mabid=0 (m0), peid=0 (p0) ^ 1 指定した場所から何ワード表示するか [num_of_words]

となっています。

「group や mab とは何?」という方は、n0c0b0m0p0 は一旦おまじないだと思ってください。

先の例は、指定された PE の $lm4 を \(1\) 個、(浮動小数点数としては Double 値として、)表示せよ、という命令です。

出力の読み方は、

DEBUG-LM0(n0c0b0m0p0,4):(0) (0x0000000000000019) #d getd $lm4n0c0b0m0p0 1 ^^^ LM0 : どのメモリか ^^^^^^^^^^ n0c0b0m0p0 : どこの PE か ^ 4 : アドレス。"$lm4" の "4" ^^^ (0) : 浮動小数点数としての値 ^^^^^^^^^^^^^^^^^^^ 0x0000000000000019 : 整数としての値

となっています。

ということでこれは、指定された PE の $lm4 には 0x19 = \(25\) が格納されていることが分かります。

$m0 などの単語を表示させたい際は、Int でも Float でも、getd の代わりに getf を使います。

d getn0c0b0m0p0 の部分は、どのメモリを表示したいか編集する際によく誤って一部を消してしまい(特に先頭の n0)、意図しない動作を引き起こすことが多々あるので、注意してください。

連続領域の値を取得

連続した領域を表示するには、[num_of_words] を使用すると便利です。

d getd $lm0n0c0b0m0p0 4

は、

d getd $lm0n0c0b0m0p0 1 d getd $lm2n0c0b0m0p0 1 d getd $lm4n0c0b0m0p0 1 d getd $lm6n0c0b0m0p0 1

と同等の結果を得られます。

複数の PE の値を取得

n0c0b0m0p0 の部分を適宜省略すると、複数の PE の値を取得できます。

peid = 0 を指定していた p0 を省略すると、範囲内の全 PE の値を取得できます。

d getd $lm0n0c0b0m0 1

は、

d getd $lm0n0c0b0m0p0 1 d getd $lm0n0c0b0m0p1 1 d getd $lm0n0c0b0m0p2 1 d getd $lm0n0c0b0m0p3 1

と同等の結果を得られます。

d set : 値を設定する

以下のように、d set を使い、\(16\) 進数で表現された整数値を設定することもできます。

これは LM0 の \(0\) 番地 ($ln0) に \(1\) 長語、長語値 \(3\) を書き込む、という指示です。

d set $ln0 1 l3

コードテスト で実行する際は「d set を有効にする」にチェックを入れてください。ローカルで judge.py を使用する際は --enable-set オプションが必要です。

以下のコードは $ln0 から \(4\) 長語、長語値 \(16,32,48,64\) を書き込む、というものです。

d set $ln0 4 l10l20l30l40

以下の様に単語のロケーションを指定することもできますが、書き込み値は長語値を受け取るため、各長語の下位の単語は無視されます。

d set $n0 2 s1_2s3_4 # s1_2 は 単語 (Single) 値を 2 つで長語を表します。つまり l100000002 と同じです。 d getf $n0n0c0b0m0p0 2 # $n0, $n1 を表示して確認

出力は以下の通りです。

DEBUG-LM1(n0c0b0m0p0,0):(0) (0x00000001) #d getf $n0n0c0b0m0p0 2 DEBUG-LM1(n0c0b0m0p0,1):(0) (0x00000003) #d getf $n0n0c0b0m0p0 2

LM1(n0c0b0m0p0,0) = $n0 には \(1\) が、LM1(n0c0b0m0p0,1) = $n1 には \(3\) が格納された事が分かります。

PE を指定して書き込み

d set では PE を指定して、特定の PE に値を書き込むこともできます。

d get のときと同じく、 $ln0n0c0b0m0p0 のようにロケーションを指定すると、対象の PE にのみ値が書き込まれます。

d set $ln0n0c0b0m0p0 1 l100