前回の終わりに169行目にジャンプしたところから再開します。
今回読むのは以下の部分です。
[Rn, Rm]はMem[Rn + Rm]ですから、
次に進みます。
セクションから1減算し、ゼロでなければラベル2にジャンプする、という処理になりますね。つまり、今回読んでいるソースはn_secでループしているわけですね。
ループを抜けると、再びラベル3の処理に入ります。そして、新しいMMU_INITマクロで設定したva, pa, n_sec, attrを読み込んで、vaとpaを適切に変換して、また、今回読んだループに入るというわけです。二重ループをこうやって実現しているんですね。
しかし、よくわからないのが173行目にあるbhiのhiです。
これは、キャリーフラグが1かつゼロフラグが0である、という意味になります。
キャリーフラグが1とは桁あふれが発生した場合で、ゼロフラグが0とは命令の結果が0でない(0ならフラグは1)である、という意味です。
なるほど、n_secから1を引いたときにゼロになればゼロフラグが1になりそうです。
一方で、キャリーフラグはn_secつまり0x06や0x10からマイナス1されるだけなので、ちっとも桁あふれなど起きなさそうです。
良く考えると、マイナス1を2の補数で表すと全部の桁が1になります。全部の桁が1に対して正の数を足せば、桁あふれが起きそうな気がします。もしかすると、それでキャリーフラグが立つのかもしれません。
だったら、ゼロフラグだけ見ていればよい気もします。すっきりしないなぁ。
すっきりしませんが、今回読んだ部分をCっぽく書いて終わりにしましょう。
今回読むのは以下の部分です。
169 2: str pa, [l1table, va] 170 add va, va, #4 171 add pa, pa, #(L1_S_SIZE) 172 adds n_sec, n_sec, #-1 173 bhi 2bまずは169行目から。
169 2: str pa, [l1table, va]strはストア命令です。無印なので32ビットストアですね。レジスタpaをアドレス[l1table, va]にストアします。角かっこがいやらしいですね。
[Rn, Rm]はMem[Rn + Rm]ですから、
*(l1table + va) = pa;ということになります。Ll1_tableは.word 0x4000の空間でしたね。
170 add va, va, #4 171 add pa, pa, #(L1_S_SIZE)addは加算ですね。L1_S_SIZEはセクションのサイズ、つまり1MBですから
va += 4; pa += 0x00100000; /* L1_S_SIZEは1M */となります。
次に進みます。
172 adds n_sec, n_sec, #-1 173 bhi 2baddsのaddは加算命令で、のこりのsはステータスレジスタの更新あり、でしたね。
セクションから1減算し、ゼロでなければラベル2にジャンプする、という処理になりますね。つまり、今回読んでいるソースはn_secでループしているわけですね。
ループを抜けると、再びラベル3の処理に入ります。そして、新しいMMU_INITマクロで設定したva, pa, n_sec, attrを読み込んで、vaとpaを適切に変換して、また、今回読んだループに入るというわけです。二重ループをこうやって実現しているんですね。
しかし、よくわからないのが173行目にあるbhiのhiです。
これは、キャリーフラグが1かつゼロフラグが0である、という意味になります。
キャリーフラグが1とは桁あふれが発生した場合で、ゼロフラグが0とは命令の結果が0でない(0ならフラグは1)である、という意味です。
なるほど、n_secから1を引いたときにゼロになればゼロフラグが1になりそうです。
一方で、キャリーフラグはn_secつまり0x06や0x10からマイナス1されるだけなので、ちっとも桁あふれなど起きなさそうです。
良く考えると、マイナス1を2の補数で表すと全部の桁が1になります。全部の桁が1に対して正の数を足せば、桁あふれが起きそうな気がします。もしかすると、それでキャリーフラグが立つのかもしれません。
だったら、ゼロフラグだけ見ていればよい気もします。すっきりしないなぁ。
すっきりしませんが、今回読んだ部分をCっぽく書いて終わりにしましょう。
do { *(l1table + va) = pa; va += 4; pa += 0x00100000; /* L1_S_SIZEは1M */ } while (--n_sec > 0)