[解決済み] BL命令ARM - その仕組み
質問事項
ARM Assemblyを勉強しているのですが、今、行き詰まっていることがあります。
リンクレジスターについては知っています。間違っていなければ、関数呼び出しが完了したときに戻るアドレスを保持しています。
というようなものがあれば(ARMのドキュメントから引用)。
0 | here
1 | B there
2 |
3 | CMP R1, #0
4 | BEQ anotherfunc
5 |
6 | BL sub+rom ; Call subroutine at computed address.
つまり、左の列を各命令のアドレスと考えると、そこのBのアドレス1の後、リンク・レジスタは1の値を保持していることになりますね。
そして、プログラムはそこのメソッドに行き、リンクレジスターの値を使って戻る場所を知るのです。
今、私が行き詰っている6番地まで飛ばすと、次の命令のアドレスをどのBLがlr(r14、リンクレジスタ)にコピーしているかが分かります。
ということは、今度はサブルーチンであるsubのアドレス(サブルーチンって何?)+rom(数字?
しかし、一般的に、BLはどんな時に必要なのでしょうか?上の例では、なぜそれが必要なのでしょうか?どなたか、本当に必要な例を教えてください。
ありがとうございます。
解決方法は?
少し混乱されているようですね。以下はその説明です。
は
B
命令は分岐します。他の命令にジャンプし、リターンは期待できません。リンクレジスタ(LR)は触れません。
は
BL
命令は分岐しますが、リンクもします。の後の命令のアドレスでLRがロードされます。
BL
の後に実行される命令ではなく、メモリ上の
BL
. そうすると、LRを使って分岐から戻ることができるようになります。
例:
start:
01: MOV r0, r2 ; some instruction
02: B there ; go there and never return !
there:
11: MOV r1, r0 ; some instruction
12: BL some_function ; go to some_function, but hope to return !
; this BL will load 13 into LR
13: MOV r5, r0
14: BL some_function ; this BL will load 15 into LR
15: MOV r6, r0
some_function:
MOV r0, #3
B LR ; here, we go back to where we were before
関数の中で別の関数を呼び出したい場合、LRは上書きされてしまうので、戻ることができません。一般的な解決策は、LRをスタックに保存するために
PUSH {LR}
で復帰する前に復元します。
POP {LR}
. リストアとリターンを1つの
POP {PC}
これは LR の値を復元しますが、プログラムカウンタでは事実上関数を返します。
関連
-
[解決済み】lc3 LDR命令と格納される値について
-
[解決済み】JNZとCMPのアセンブリ命令
-
[解決済み] error A2022: 命令オペランドは同じサイズでなければなりません。
-
[解決済み] ARMのアセンブリ言語でbx lrは何をするのですか?
-
[解決済み] アセンブリ - CMP後のJG/JNLE/JL/JNGE
-
[解決済み] .quadディレクティブはアセンブリでどのように機能するのですか?
-
[解決済み] ARMはSDIVとUDIVを区別していますが、ADD、SUB、MULでは区別していないのはなぜですか?
-
[解決済み] ループ内で配列の個々の要素にアクセスするにはどうしたらよいですか?
-
[解決済み] MIPSの擬似命令 "move "の "addi "と "add "の違い?
-
[解決済み】マルチコアアセンブラとはどのようなものですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】テスト %eax %eax のポイント【重複あり
-
[解決済み] テスト
-
[解決済み】x86アセンブリ。AT&Tの構文で「subl」コマンドはどのように動作するのか
-
[解決済み] MIPS: スタックポインタ($sp)とスタックの関連した使用法
-
[解決済み] エラーです。操作サイズが指定されていません - NASm
-
[解決済み] アセンブリで数字をASCIIに変換する
-
[解決済み] .quadディレクティブはアセンブリでどのように機能するのですか?
-
[解決済み] ビットシフト演算子を使って10進数を2進数で表示するMIPS
-
[解決済み] エラー: `push' の命令サフィックスが無効です [重複].
-
[解決済み] アセンブリの追加要求の明確化