メモリマップとスタック
どのメモリ番地が何に使われるかを表したものをメモリマップと呼ぶ. Raspberry Pi上で直接(OSを使わずに)実行するプログラムでは,次のメモリマップに従う.
- 〜 0x00007fff: スタック
- 0x00008000 〜: プログラム (.initセクション)
- プログラムの直後〜: データ (.dataセクション)
- 0x3f000000 〜: メモリマップI/O
プログラムは0x8000番地から高位番地に向かって配置されることになっている. リンカ(arm-none-eabi-ld)はそれに合わせて.initセクションを0x8000番地から配置するように実行ファイルを作る.
スタックは0x8000番地直前のワードから低位番地に向かって伸びる.
スタックポインタは初期化されていない ので,サブルーチンを使うプログラムのように
スタックを必要とするプログラムでは,プログラムの実行開始時にスタックポインタを初期化する必要がある.
つまり,sp
レジスタに0x8000をセットする必要がある.
.equ STACK, 0x8000
-- 中略 --
_start:
mov sp, #STACK
これを忘れてスタックへのロードやストアを行うと,CPUがエラー状態になって暴走する. (正確には割り込みの一種が発生して割り込みハンドラに制御が移るが,割り込みハンドラを定義していないため暴走する.)