プログラムを埋め込む際の制限と注意点 @分岐命令によるループの制限 分岐命令によるループとは、分岐命令で上方向へ処理を戻し 同じ処理を繰り返す物の事を指します 実例では、アイテムを持っているかどうかのチェックに ループを使って各アドレスの個数を読み込んでいたり 自作プログラムの連続書き込み再現プログラムで使用するなど ループはプログラムには欠かせない要素です。 しかし、困った事に分岐命令を使用したループには制限が存在し ある特殊な条件下において、分岐命令のループが 設定された回数繰り返す前に終了してしまう場合があります どうもバグが原因のようですが・・・ その特殊な条件というのが「ループさせた時の戻る命令数」で 分岐命令とループさせる先との間に、分岐命令を含め 6命令以上のスペースが必要になります スペースと言っても別にnopにするという訳ではなく 間に命令が存在していても行数さえ空けば良いです。 〜ループ処理悪い例〜 000F0000 lui t0, $0034 000F0004 addiu t1, zero, $001E 1 000F0008 addiu t2, zero, $270F 2 000F000C sw t2, $5678(t0) 3 000F0010 addiu t0, t0, $0004 4 000F0014 addiu t1, t1, $FFFF 5 000F0018 bne t1, zero, $000F0008 〜ループ処理良い例〜 000F0000 lui t0, $0034 000F0004 addiu t1, zero, $001E 1 000F0008 addiu t2, zero, $270F 2 000F000C nop 3 000F0010 sw t2, $5678(t0) 4 000F0014 addiu t0, t0, $0004 5 000F0018 addiu t1, t1, $FFFF 6 000F001C bne t1, zero, $000F0008 高速化改造で使用するVSyncプログラムを見ると分かりますが このループ制限に沿ってスペースが空けられていますAプログラムエリアとデータエリアの境界線 自分でテーブル管理を作成したりする場合の注意点がこれで プログラム部分とプログラムではない数値部分の境界線に 最低でも5つ以上のnop命令が必要になります。 実例ではゼノサーガエピソード1の 「特定キャラのステータスMAX」コードの 000F5000 lui t0,$0041 000F5004 ori t0,t0,$d800 〜中略〜 000F5030 jr ra -------------------------------- 000F5100 0063270F 000F5104 03E703E7 000F5108 03E703E7 000F510C 00636363 点線部分から上がプログラムエリア 点線部分から下がプログラムではないデータエリアとなりますが プログラム末尾の000F5030からテーブルまでの間に 5つ以上のnopがあるので動作に問題はありませんが これがもし以下の様であるとnopが足りず不具合が出る可能性があります 000F5000 lui t0,$0041 000F5004 ori t0,t0,$d800 〜中略〜 000F5030 jr ra -------------------------------- 000F5040 0063270F 000F5044 03E703E7 000F5048 03E703E7 000F504C 00636363 この制限の対策法はもう1つあり、プログラムとデータとの境界線に 「1つのnopとsync.p命令を入れる」という方法でも回避できます しかし、コードにすると1行は余分に増えるのでオススメしません。