armアセンブラを書く上で便利なことをまとめます。\\ ====== 関数呼び出し ====== bl 相対アドレスジャンプ。ただし、遠くへは飛べない。 b 無条件ジャンプ。ただし、遠くへは飛べない。 blとbの違いは、8086でいう callとjmpです。\\ 現在実行している番地はpc(r15レジスタ)に格納されいます。\\ pcを書き換えることでjmpを実現します。\\ \\ 戻り先の定義は、blの場合は、スタックではなく lr(r14レジスタ)を利用します。\\ \\ 絶対番地へ問答無用で飛ばしたい場合は、次のようにする。\\ \\ ・blを置き換える命令\\ ldr r1,=$08AABBCC ;bl 08AABBCC の置き換え mov lr, r1 @dcw $F800 ; pcとlrレジスタを置き換えて、戻り先の確保と、実行番地を飛ばす. GASだと、blhマクロを利用すると便利です。 .macro blh to, reg=r3 ldr \reg, =\to mov lr, \reg .short 0xf800 .endm blh 0x08AABBCC ・bを置き換える命令\\ ldr r1,=$08AABBCC  ;b 08AABBCC の置き換え mov pc, r1 ;pcを置き換えて飛ばす. ;生成されるasmコードの1バイト目が0x00になるので、 ;コピペするときは、開始バイトを確認して、0x00バイトをコピーし忘れないように。 ====== 条件分岐カンペ ====== cmp Ra,XX としたとき BEQ(Ra==XX) BNE(Ra!=XX) BGE(Ra>=XX) BGT(Ra>XX) BLE(Ra<=XX) BLT(Ra ====== 代入 ====== 数字を代入する時は、 mov を使う。\\ mov r0,#0x01 ポインタを代入するときは、ldrを使う。\\ ldr r0,=$0202BE48 ポインタを代入する時に、 movを使うと、 コンパイル(アセンブル)は成功となるが null値代入のコードが生成される。\\ mov r0,=$0202BE48 ↓ mov r0,=$00000000 ;実際にはこういうコードが生成される。危険。 ====== 逆汗とアセンブル ====== 逆アセンブラ\\ disarm -t aaa.gba > aaa.asm アセンブル\\ goldroad aaa.asm ただし、 数値データの解釈が両者異なるので注意。\\ disarmでは、 mov r1,#11 は、 r1に **0x11** を代入する意味だが、\\ goldroadでは、 mov r1,#11 は、r1に **11** を代入する意味になる。\\ \\ 取り違えると悲惨なことになるので、\\ disarmしたasmの数字データには、#0x11 と 0x をつけて16進数にしなくてはいけない。\\ mov r1,#11 ↓ mov r1,#0x11 ====== no$gba debugger ブレークポイント ====== Debug->Define Break / Conditionでブレークポイントを作れる。\\ \\ 詳細な使い方はこちらを参照 http://ngmansion.webcrow.jp/wp/2015/02/23/gba%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E6%94%B9%E9%80%A0%E3%81%AE%E6%89%8B%E5%BC%95%E3%81%8D/#nogba 08123456 0x08123456 のコードを実行したら止まる。 [0202BE48]? 0x0202BE48を読み込んだら止まる [0202BE48]! 0x0202BE48に書き込んだら止まる [0202BE48]=34 0x0202BE48に0x34が書き込まれたら止まる。(バイト指定) [0202BE48]=0xF0 0x0202BE48に0xF0が書き込まれたら止まる。(バイト指定) バグがあるらしく、A-Fを使いたい場合は、0xF0 としなければいけない。 0xを付けなくても、16進数表記なのだが、受け付けてくれない。 r0=01234567 r0レジスタが 01234567 になったら止まる r0!=01234567 r0レジスタが 01234567 以外になったら止まる r0<>01234567と同一。 便利な方法。\\ 探したい値がある場合。その値を r0 - r2 までに指定するとだいたい見つけることができる。\\ レジスタマシンなので、利用するためには、どこかでレジスタに読み込む必要があるからだ。\\ r0=1234 r1=1234 r2=1234