アセンブラとかレジスタとかのメモ

OS自作用のメモ。

エンディアン

x86_64はリトルエンディアン

汎用レジスタ

x86_64の汎用レジスタは次の16個

  1. RAX
  2. RBX
  3. RCX
  4. RDX
  5. RBP
  6. RSI
  7. RDI
  8. RSP
  9. R8
  10. R9
  11. R10
  12. R11
  13. R12
  14. R13
  15. R14
  16. R15

バイト数の異なる別名(p.71)

64bit 32bit 16bit 8bit
RAX EAX AX AH, AL
RBX EBX BX BH, BL
RCX ECX CX CH, CL
RDP EDP DP DH, DL
RSI ESI SI
RDI EDI DI
RBP EBP BP
RSP ESP SP

特殊なレジスタ

  • SS: スタックセグメントレジスタx86_64では実質的には全く利用されない)
  • CS: コードセグメントレジスタ(64ビットモードでも有効に作用する)  (これらの値から実行権限がわかる?)

関数呼び出しの引数(System V ABI)

  • RAX: 引数の数
  • RDI: 第1引数
  • RSI: 第2引数
  • RDX: 第3引数
  • RCX: 第4引数
  • R8: 第5引数
  • R9: 第6引数
  • RBP: ベースポインタ
  • RSP: スタックポインタ

ベースポインタとスタックポインタは関数終了時に呼び出し時の状態に戻す必要がある。 第7引数以降はスタックに積まれる。

ただし、システムコール時は - RCXにRIPの値が上書きされる - R11にRFLAGSの値が上書きされる

そのため、Linuxでは第4引数にRCXの代わりにR10を使う。

  • RAX: 返り値 / 引数の数
  • RDI: 第1引数
  • RSI: 第2引数
  • RDX: 第3引数
  • R10: 第4引数
  • R8: 第5引数
  • R9: 第6引数 第7引数以降はスタックに積まれる。

戻り値(System V AMD64 ABI)

  1. RAX
  2. RDX(RAXだけでは足りないとき)

x86_64の演算命令

2つのオペランド(引数)をとる

  • 命令(オペコード)
  • 左側:書き込み先
  • 右側:読み込み元

  • sti: 割り込み許可(Set Interrupt-Enable Flag)

  • cli: 割り込み禁止(Clear Interrupt-Enable Flag)
  • hlt: CPUを省電力モードに切り替え、次の割り込みまで命令の実行を停止する。
  • lidt: CPUにIDTテーブル(Interrupt Descriptor Table)を登録する。
  • lgdt: GDTのアドレスをGDTRレジスタに設定
  • retf: far call(異なるコードセグメントにある関数へのジャンプ)から復帰するときに使う命令、スタックから戻り先アドレスとCSの値を設定する。(コンテクストスイッチや権限切り替え時に利用?)
  • lea dst, [src] srcのアドレス計算結果をdstに格納する。(movの場合はsrcのアドレスが指す値を格納する。)