[Arm64] ストア命令

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

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

  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ビット

  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ビット

  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ビット

  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

    ADR     Xd, label
    ADRP    Xd, label

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

    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つのレジスタに読み込む命令

    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) にオフセットの値を加えたアドレスを先頭とするメモリに書き込み、レジスタをスタックに退避する場合によく使う

    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}]