とあるエンジニアの備忘log
2012年11月8日木曜日
ARM のスタックについて
### Stack のポリシー ### まずは一般論から。 Stack Pointer の指している先にデータがあるかないかで以下のように分かれる。 - Full Stack: Stack Pointer は最後に使用された位置を指している - Empty Stack: Stack Pointer は未使用な最初の位置を指している また、アドレスが小さくなる方に成長するか、アドレスが大きくなる方に成長するかで以下のように分かれる。 - 下降スタック : メモリアドレスの降順に増加 - 上昇スタック : メモリアドレスの昇順に増加 だから、スタックのポリシー的には 2 X 2 = 4 通りが可能ということになる。 ### ARM の場合 ### どれを採用するかは ABI で決められることだが、 ARM では Full & 下降スタックを使うようだ。 ARM の `LDM`, `STM` 命令は表記がいろいろあって、よく忘れるのでメモっておく。 まず表記法として、非スタックアドレッシングとスタックアドレッシングがある。 非スタックアドレッシングは - `LDMDA` (Decrement After) - `LDMIA` (Increment After) - `LDMDB` (Decrement Before) - `LDMIB` (Increment Before) - `STMDA` (Decrement After) - `STMIA` (Increment After) - `STMDB` (Decrement Before) - `STMIB` (Increment Before) という表記になる。 ARM では Full スタック、下降スタックを採用するというのだから、 push するときには `STMDB` 命令を使用し、 pop するときには `LDMIA` 命令を使用しないといけない。 で、常にこういうことを考えるのも面倒なので、スタックアドレッシングの表記も用意されている - `LDMFA` (Full Ascending) - `LDMFD` (Full Desending) - `LDMEA` (Empty Ascending) - `LDMFD` (Empty Descending) - `STMFA` (Full Ascending) - `STMFD` (Full Desending) - `STMEA` (Empty Ascending) - `STMFD` (Empty Descending) で、非スタックアドレッシングとスタックアドレッシングの関係だが、以下は同じになる。 Non-stack / Stack adressing LDMDA = LDMFA LDMIA = LDMFD (= pop) LDMDB = LDMEA LDMIB = LDMED STMDA = STMED STMIA = STMEA STMDB = STMFD (= push) STMIB = STMFA そういうわけで、 関数のプロローグのよくある STMDB r13!, {r4-r7, r9, r14} という命令は STMFD r13!, {r4-r7, r9, r14} とも書けるし、さらに簡単に push {r4-r7, r9, r14} とも書ける。 `!` はオートインデックス指定。 同様に、関数のエピローグでは LDMIA r13!, {r4-r7, r9, r15} は LDMFD r13!, {r4-r7, r9, r15} とも書けるし、さらに簡単に pop {r4-r7, r9, r15} とも書ける。 `push`, `pop` 表記が使えるのは gcc だからかもしれない。(未確認)
0 件のコメント:
コメントを投稿
次の投稿
前の投稿
ホーム
登録:
コメントの投稿 (Atom)
0 件のコメント:
コメントを投稿