[Arm64] ロード命令

ロード命令(LDR)はメモリに格納されている値をレジスタに読み込み、ストア命令はレジスタに入っている値をメモリに書き出す

LDR : メモリからレジスタ
STR : レジスタからストア
MOV : レジスタからレジスタ

ロード/ストア命令は読み書きするメモリの位置を指定する必要があり、アドレッシングという
x86, x64, ARM, PowerPCによってアドレッシングの方法が異なる
ARM64ではイミディエートオフセットと レジスターオフセットなどがある。
ベースレジスタのオフセット(加算)を使用する
イミディエートオフセットは定数、レジスターオフセットはレジスタの格納された値

LDR Xt, [base, #simm9]

	base = base + simm9;
	Xt = memory[base];
LDR Xt, [base, #uimm12]
	Xt = [base + uimm12 * scale];

### レジスタオフセット
ベースレジスタ(Xn または SP)が保持しているメモリアドレスにインデックス用のレジスタが格納しているオフセット値を加えたメモリアドレスをXtにコピー

LDR Xt, [base, Wm {, SXTW|UXTW {#0|#3}}]
LDR Xt, [base, Xm {, LSL|SXTX {#0|#3}}]

	Xt = memory[base + {* 8}];

### ロード命令
メモリが64, 32, 16, 8ビットあり、レジスタが32ビット(Wt)と64ビット(Xt)があるため、ビットに応じてそれぞれ命令がある
ビット幅を増やすには符号拡張とするか、ゼロ拡張を行う

### ロード命令の詳細
6種類のアドレッシング
9ビット符号付即値+ポストインデックス
9ビット符号付即値+プレインデックス
9ビット符号付即値
12ビット符号なし即値
32ビットレジスタオフセット
64ビットレジスタオフセット

### (1)LDR ダブルワード(64ビット) → 64ビット

  LDR   Xt, [base], #simm9       // ポストインデックス
  LDR   Xt, [base,  #simm9]!     // プレインデックス
  LDUR  Xt, [base,  #simm9]
  LDR   Xt, [base {,#uimm12} ]   // 符号なしオフセット(8の倍数) [0 - 32760] 
  LDR   Xt, [base, Wm {,SXTW|UXTW {#0 | #3}} ]  // レジスタオフセット
  LDR   Xt, [base, Xm {,LSL|SXTX {#0 | #3}} ]  // レジスタオフセット

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

  LDR   Wt, [base], #simm9     // ポストインデックス
  LDR   Wt, [base,  #simm9]!   // プレインデックス
  LDUR  Wt, [base,  #simm9]
  LDR   Wt, [base {,#uimm12} ]  // 符号なしオフセット(4の倍数) [0 - 16380] 
  LDR   Wt, [base, Wm {,SXTW|UXTW {#0 | #2}} ] 
  LDR   Wt, [base, Xm {,LSL|SXTX {#0 | #2}} ] 

### (3)LDRSW 符号付きワード(32ビット) → 64ビット

  LDRSW  Xt, [base], #simm9     // ポストインデックス
  LDRSW  Xt, [base,  #simm9]!    // プレインデックス
  LDURSW Xt, [base,  #simm9]
  LDRSW  Xt, [base {,#uimm12} ]  // 符号なしオフセット(4の倍数) [0 - 16380]
  LDRSW  Xt, [base, Wm {,SXTW|UXTW {#0 | #2}} ]
  LDRSW  Xt, [base, Xm {,LSL|SXTX {#0 | #2}} ]

### (4)LDRH ハーフワード(16ビット) → 32ビット

  LDRH  Wt, [base], #simm9      // ポストインデックス
  LDRH  Wt, [base,  #simm9]!     // プレインデックス
  LDURH Wt, [base,  #simm9]
  LDRH  Wt, [base {,#uimm12} ]   // 符号なしオフセット(2の倍数) [0 - 8190]
  LDRH  Wt, [base, Wm {,SXTW|UXTW {#0 | #1}} ]
  LDRH  Wt, [base, Xm {,LSL|SXTX  {#0 | #1}} ]

### (5) LDRSH 符号付きハーフワード(16ビット) → 32ビット

  LDRSH  Wt, [base], #simm9     // ポストインデックス
  LDRSH  Wt, [base,  #simm9]!   // プレインデックス
  LDURSH Wt, [base,  #simm9]
  LDRSH  Wt, [base {,#uimm12} ]  // 符号なしオフセット(2の倍数) [0 - 8190]
  LDRSH  Wt, [base, Wm {,SXTW|UXTW {#0 | #1}} ] 
  LDRSH  Wt, [base, Xm {,LSL|SXTX  {#0 | #1}} ] 

### (6) LDRSH 符号付きハーフワード(16ビット) → 64ビット

  LDRSH  Xt, [base], #simm9     // ポストインデックス
  LDRSH  Xt, [base,  #simm9]!   // プレインデックス
  LDURSH Xt, [base,  #simm9]
  LDRSH  Xt, [base {,#uimm12} ]  // 符号なしオフセット(2の倍数) [0 - 8190]
  LDRSH  Xt, [base, Wm {,SXTW|UXTW {#0 | #1}} ] 
  LDRSH  Xt, [base, Xm {,LSL|SXTX {#0 | #1}} ] 

### (7)LDRB バイト(8ビット) → 32ビット

  LDRB  Wt, [base], #simm9     // ポストインデックス
  LDRB  Wt, [base,  #simm9]!    // プレインデックス
  LDURB Wt, [base,  #simm9]
  LDRB  Wt, [base {,#uimm12} ]  // 符号なしオフセット [0 - 4095]
  LDRB  Wt, [base, Wm {,SXTW|UXTW {#0}} ]
  LDRB  Wt, [base, Xm {,LSL|SXTX  {#0}} ]

### (8)LDRSB 符号付きバイト(8ビット) → 32ビット

  LDRSB  Wt, [base], #simm9     // ポストインデックス
  LDRSB  Wt, [base,  #simm9]!   // プレインデックス
  LDURSB Wt, [base,  #simm9]
  LDRSB  Wt, [base {,#uimm12} ]  // 符号なしオフセット [0 - 4095]
  LDRSB  Wt, [base, Wm {,SXTW|UXTW {#0}} ] 
  LDRSB  Wt, [base, Xm {,LSL|SXTX {#0}} ] 

### (9)LDRSB 符号付きバイト(8ビット) → 64ビット

  LDRSB  Xt, [base], #simm9     // ポストインデックス
  LDRSB  Xt, [base,  #simm9]!   // プレインデックス
  LDURSB Xt, [base,#simm9]
  LDRSB  Xt, [base {,#uimm12} ]  // 符号なしオフセット [0 - 4095]
  LDRSB  Xt, [base, Wm {,SXTW|UXTW {#0}} ] 
  LDRSB  Xt, [base, Xm {,LSL|SXTX  {#0}} ] 

### PC相対リテラルアドレッシング
ラベルの位置にあるデータをレジスタに読み込む

LDR     Xt, label
LDRSW   Xt, label
LDR     Wt, label