Skip to content
Go back

ARMv4Tアーキテクチャ

· Updated:

ARMv4Tについて個人的にまとめたものです。内容には間違いが含まれている場合があります。

呼び出し規約

  • 呼び出し元:
    1. 第1引数から第4引数をr0からr3に入れる
    2. 以降の引数をスタックに積む
    3. リンク付きでジャンプする(bl
  • 呼び出し先:
    1. push lr
    2. 呼び出し元のレジスタ状態を保存する
    3. 処理を行う
    4. 戻り値をr0に入れる
    5. 呼び出し元のレジスタ状態を復元する
    6. pop lr
    7. bx lr

レジスタ

  • r0-r3は呼び出された側によって内容が維持されない
  • r4-r11は呼び出された側によって内容が維持される
番号別名用途
r0a1引数を渡す、計算を行う、戻り値を返す
r1a2引数を渡す、計算を行う
r2a3
r3a4
r4v1計算を行う
r5v2
r6v3
r7v4
r8v5
r9v6
r10v7
r11v8,fpFrame Pointer. 呼び出された時点でのスタックの先頭へのアドレスを入れる
r12ipIntra-Procedure-call scratch register
r13spStack Pointer. スタックの先頭へのアドレスを入れる
r14lrLink Register. リターン先へのアドレスが入る
r15pcProgram Counter. 実行するプログラムへのアドレスが入る

ARM命令

表記法

名前記法説明
条件コード{cond}CPSRの条件コードフラグが指定の状態を満たしていれば、その命令を実行する
オペランド2<operand2>即値かレジスタから値を指定する。レジスタではシフト演算ができる
フィールド{field}PSRのビットマスクを指定する
条件コードセットS条件コードフラグを更新する
レジスタリスト<reglist>レジスタのリスト。{r0, r1, r2}と記述する

条件コード cond

接尾辞意味条件
EQ等価Z == 1
NE非等価Z == 0
CS以上(符号なし)C == 1
CC未満(符号なし)C == 0
MI負数N == 1
PL非負数N == 0
VSオーバーフローV == 1
VC非オーバーフローV == 0
HI大きい(符号なし)C == 1 && Z == 0
LS小さい(符号なし)C == 0 && Z == 1
GE以上N == V
LT未満N != V
GT大きいZ == 0 && N == V
LE小さいZ == 1 | N != V
AL常時true

アドレッシングモード

モード2 <a_mode2>
通常
  • Rnにオフセット値を加えた値をアドレスとする
  • Rnは変化しない
タイプ構文
即値オフセット[Rn, #+/-12ビット数値]
レジスタオフセット[Rn, +/-Rm]
レジスタオフセット(論理左シフト)[Rn, +/-Rm LSL \#5ビット即値]
レジスタオフセット(論理右シフト)[Rn, +/-Rm LSR \#5ビット即値]
レジスタオフセット(算術左シフト)[Rn, +/-Rm ASR \#5ビット即値]
レジスタオフセット(右ローテート)[Rn, +/-Rm ROR \#5ビット即値]
レジスタオフセット(拡張右ローテート)[Rn, +/-Rm LSL \#5ビット即値]
Pre-indexed
  • Rnにオフセット値を加えた値をアドレスとする
  • Rnはオフセット値を加えた値になる
タイプ構文
即値[Rn, #+/-12ビット数値]!
レジスタ[Rn, +/-Rm]!
レジスタ(論理左シフト)[Rn, +/-Rm LSL \#5ビット即値]!
レジスタ(論理右シフト)[Rn, +/-Rm LSR \#5ビット即値]!
レジスタ(算術左シフト)[Rn, +/-Rm ASR \#5ビット即値]!
レジスタ(右ローテート)[Rn, +/-Rm ROR \#5ビット即値]!
レジスタ(拡張右ローテート)[Rn, +/-Rm LSL \#5ビット即値]!
Post-indexed
  • Rnの値をアドレスとする
  • Rnはオフセット値を加えた値になる
タイプ構文
即値[Rn], #+/-12ビット数値
レジスタ[Rn], +/-Rm
レジスタ(論理左シフト)[Rn], +/-Rm LSL \#5ビット即値
レジスタ(論理右シフト)[Rn], +/-Rm LSR \#5ビット即値
レジスタ(算術左シフト)[Rn], +/-Rm ASR \#5ビット即値
レジスタ(右ローテート)[Rn], +/-Rm ROR \#5ビット即値
レジスタ(拡張右ローテート)[Rn], +/-Rm LSL \#5ビット即値
モード3 <a_mode3>
タイプ構文
即値オフセット[Rn, #+/-8ビット数値]
Pre-indexed[Rn, #+/-8ビット数値]!
Post-indexed[Rn], #+/-8ビット数値
レジスタ[Rn, +/-Rm]
Pre-indexed[Rn, +/-Rm]!
Post-indexed[Rn], +/-Rm

オペランド2

タイプ構文
即値\#32ビット即値
論理左シフトRm LSL \#5ビット即値
論理右シフトRm LSR \#5ビット即値
算術右シフトRm ASR \#5ビット即値
右ローテートRm ROR \#5ビット即値
レジスタRm
論理左シフトRm LSL Rs
論理右シフトRm LSR Rs
算術右シフトRm ASR Rs
右ローテートRm ROR Rs
拡張右ローテートRm RRX

フィールド

接尾辞意味マスク
_c制御フィールド0x000000ff
_x拡張フィールド0x0000ff00
_sステータスフィールド0x00ff0000
_fフラグフィールド0xff000000

移動

名前構文説明
移動MOV{cond}{S} Rd, <operand2><operand2>の値をRdに入れる
SPSRから移動MSR{cond} Rd, SPSRSPSRの値をRdに入れる
CPSRから移動MSR{cond} Rd, CPSRCPSRの値をRdに入れる
SPSRへ移動MSR{cond} SPSR{filed}, RmRmの値をSPSRに入れる
CPSRへ移動MSR{cond} CPSR{filed}, RmRmの値をCPSRに入れる

算術

名前構文説明
減算SUB{cond}{S} Rd, Rn, <operand2>Rnの値から<operand2>の値を減算してRdに入れる

論理

名前構文説明
論理和ORR{cond}{S} Rd, Rn, <operand2>Rn<operand2>の論理和をRdに入れる
ビットクリアBIC{cond}{S} Rd, Rn, <operand2><operand2>の値で指定したビットを0にしたRnの値をRdに入れる

分岐

名前構文説明
分岐B{cond} labellabelにジャンプする
リンク付き分岐BL{cond} labelリンク付き分岐。復帰アドレスをr14にストアしてlabelにジャンプする
分岐交換命令セットBX{cond} RnCPUステートを切り替えてRnにジャンプする。Rnの1ビット目が0ならばARMステートに、そうでなければThumbステートに切り替わる。
  • ARMv4TではBLXは使えない

ロード

名前構文説明
ワードLDR{cond} Rd, <a_mode2><a_mode2>が指すアドレスから32ビットをRdに読み出す
ハーフワードLDR{cond}H Rd, <a_mode3><a_mode3>が指すアドレスから16ビットをRdに読み出す
ハーフワード(符号付き)LDR{cond}SH Rd, <a_mode3><a_mode3>が指すアドレスから16ビットをRdに符号を考慮して読み出す
バイトLDR{cond}B Rd, <a_mode2><a_mode2>が指すアドレスから8ビットをRdに読み出す
バイト(符号付き)LDR{cond}SB Rd, <a_mode2><a_mode2>が指すアドレスから8ビットをRdに符号を考慮して読み出す
ブロック間転送(ポストインリメント)LDM{cond}IA Rd{!}, <reglist>{^}各転送の後にアドレスをインリメントしながら複数のレジスタへ読み出す。!を付けるとRdに結果を書き戻す。(^はユーザーモードでは使わない)

疑似命令

構文説明
LDR{cond} Rd, =exprexprの値が表現できる範囲内であれば、そのMOVMVNを生成する。そうでなければ、exprの値をリテラルプールに配置してLDRを生成する。
LDR{cond} Rd, =labellabelの値をリテラルプールに配置してLDRを生成する。
ADR Rd, labellabelのアドレスをRdに入れる

ストア

名前構文説明
ワードSTR{cond} Rd, <a_mode2>Rdの値を<a_mode2>が指すアドレスに32ビット分だけ書き出す
ハーフワードSTR{cond}H Rd, <a_mode3>Rdの値を<a_mode3>が指すアドレスに16ビット分だけ書き出す
バイトSTR{cond} Rd, <a_mode2>Rdの値を<a_mode2>が指すアドレスに8ビット分だけ書き出す
ブロック間転送(プレデクリメント)STM{cond}DB Rd{!}, <reglist>{^}各転送の前にアドレスをデクリメントしながら複数のレジスタに書き出す。!を付けるとRdに結果を書き戻す。(^はユーザーモードでは使わない)

スタック操作

名前構文説明
プッシュPUSH <reglist>レジスタは若い番号が後になるように積まれる。STMDBと同等。
ポップPOP <reglist>レジスタは若い番号が先になるように取り出される。LDRIAと同等。

ソフトウェア割り込み

名前構文説明
ソフトウェア割り込みSWI 24ビット即値指定のOSの機能をスーパーバイザーモードで実行する

GAS

用語

  • ロケーションカウンタ:物理的なアドレスを計算するための論理的なアドレス
  • リテラルプール:即値で表現できない定数を持つ命令を扱うために必要なリテラルを配置するための領域

シンボル

ラベル

  • 末尾が:のシンボル
  • 記述された位置でのロケーションカウンタを示す

ディレクティブ

構文説明
.arm以下がARM命令であることを示す
.align alignment, {fill=0}, {max=alignment}alignmentで指定されるアライメントを満たすにようにロケーションカウンタを調整する。挿入された領域はfillで初期化される。挿入された領域がmaxバイトより大きい場合、アライメントされない。(alignmentはアーキテクチャによって、バイト数であったりマスクであったりする)
.balign alignment, {fill=0}, {max=alignment}alignmentのバイト数にアライメントされるようにロケーションカウンタを調整する。挿入された領域はfillで初期化される。挿入された領域がmaxバイトより大きい場合、アライメントされない。
.fill repeat, {size=1}, {value=0}repeat個のsizeバイトの値valueで埋める
.global symbolsymbolをリンカから見えるようにする
.poolリテラルプールを明示的に配置する
  • {arg=default}は既定値defaultを持つ省略可能な引数argを示す
  • ,は適宜省略できる

参考文献