[Arm64] ストア命令

ストア命令(STR)はレジスタに格納されている値をメモリに書き込む
転送元 Wt, Xt
命令 STR, STR, STRH, STRB

### (1)STR ダブルワード(64ビット) → 64ビット
64ビットレジスタのデータをメモリにコピー

1
2
3
4
5
6
STR   Xt, [base], #simm9      // ポストインデックス
STR   Xt, [base, #simm9]!     // プレインデックス
STUR  Xt, [base {,#simm9}]   
STR   Xt, [base {,#uimm12}] 
STR   Xt, [base, Wm {,SXTW|UXTW {#0 | #3}} ]  // レジスタオフセット
STR   Xt, [base, Xm {,LSL|SXTX {#0 | #3}} ]   // レジスタオフセット

### (2)STR ワード(32ビット) → 32ビット

1
2
3
4
5
6
STR   Wt, [base], #simm9       // ポストインデックス
STR   Wt, [base, #simm9]!      // プレインデックス
STUR  Wt, [base {,#simm9} ]   
STR   Wt, [base {,#imm12} ]   
STR   Wt, [base, Wm {,SXTW|UXTW {#0 | #2}} ]  // レジスタオフセット
STR   Wt, [base, Xm {,LSL|SXTX {#0 | #2}} ]   // レジスタオフセット

### (3)STRH ハーフワード(32ビット) → 16ビット

1
2
3
4
5
6
STRH  Wt, [base], #simm9      // ポストインデックス
STRH  Wt, [base, #simm9]!     // プレインデックス
STURH Wt, [base {,#simm9}]
STRH  Wt, [base {,#uimm12}]   // 符号なしオフセット
STRH  Wt, [base, Wm {,SXTW|UXTW {#0 | #1}} ]  // レジスタオフセット
STRH  Wt, [base, Xm {,LSL|SXTX {#0 | #1}} ]   // レジスタオフセット

### (4)STRB バイト(32ビット) → 8ビット

1
2
3
4
5
6
STRB  Wt, [base], #simm9        // ポストインデックス
STRB  Wt, [base, #simm9]!       // プレインデックス
STURB Wt, [base {,#simm9}]
STRB  Wt, [base {,#uimm12}]     // 符号なしオフセット
STRB  Wt, [base, Wm {,SXTW|UXTW {#0}} ]  // レジスタオフセット
STRB  Wt, [base, Xm {,LSL|SXTX {#0}} ]   // レジスタオフセット

### PC相対アドレス計算
ラベル位置のアドレスをレジスタに設定

ADR, ADRP

1
2
ADR     Xd, label
ADRP    Xd, label

### レジスタペアのロード/ストア命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
LDP   Xt1, Xt2, [base,  #simm7]!     // プレインデックス
LDP   Wt1, Wt2, [base,  #simm7]!     // プレインデックス
 
  // プレインデックス
  base = base + simm7;
  Rt1 = memory[base];
  Rt2 = memory[base + 4|8];
 
LDP   Xt1, Xt2, [base], #simm7      // ポストインデックス
LDP   Wt1, Wt2, [base], #simm7      // ポストインデックス
 
  // ポストインデックス
  Rt1 = memory[base];
  Rt2 = memory[base + 4|8];
  base = base + simm7;
 
LDP   Xt1, Xt2, [base, #simm7]      // base への書き戻しなし
LDP   Wt1, Wt2, [base, #simm7]      // base への書き戻しなし
 
  Rt1 = memory[base];
  Rt2 = memory[base + simm7];

LDPは連続したメモリから2つのレジスタに読み込む命令

1
2
3
4
5
6
7
8
LDP   Xt1, Xt2, [base], #simm7
LDP   Wt1, Wt2, [base], #simm7
 
LDP     Xt1, Xt2, [base, #simm7]!
LDP     Wt1, Wt2, [base, #simm7]!
 
LDP     Xt1, Xt2, [Xn {, #simm7}]
LDP     Wt1, Wt2, [Xn {, #simm7}]

STP命令は二つのレジスタの内容(Xt1, Xt2)をメモリアドレスを保持するレジスタ (Xn) にオフセットの値を加えたアドレスを先頭とするメモリに書き込み、レジスタをスタックに退避する場合によく使う

1
2
3
4
5
6
STP     Xt1, Xt2, [base], #simm7
STP     Wt1, Wt2, [base], #simm7
STP     Xt1, Xt2, [base, #simm7]!
STP     Wt1, Wt2, [base, #simm7]!
STP     Xt1, Xt2, [base {, #simm7}]
STP     Wt1, Wt2, [base {, #simm7}]