Open1

ABIについて

r1rur1ru

x64

Microsoft x64 ABI

  1. 関数の引数
第一引数 第二引数 第三引数 第四引数
rcx rdx r8 r9

浮動小数点型の時は第一引数から順番にxmm0,xmm1,xmm2,xmm3を使う。
それ以上の引数はスタックに積んで渡す。

  1. 返り値
    スカラ―値はrax。非スカラ―値はxmm0で返される。

  2. レジスタの退避
    呼び出し先退避レジスタはrbx,rbp,rdi,rsi,rsp,r12-r15,xmm6-xmm15。呼び出されたプロシジャー自身が退避・復旧する。関数の中でこれらのレジスタを使用する場合は関数内で元に戻す必要がある。呼び出し元退避レジスタは上記以外のレジスタであり、関数を呼び出す側が呼び出し前に退避し、呼び出し後に復旧する。

https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-170

System V AMD64 ABI

x86-64向けのものでLinuxで標準的に使われている。

  1. 関数の引数
第一引数 第二引数 第三引数 第四引数 第五引数 第六引数
rdi rsi rdx rcx r8 r9

これ以降はスタック。引数が浮動小数点数の場合は順にxmm0,xmm1...のようにする。

  1. 返り値
    返り値はraxかrcx。浮動小数点の場合はxmm0。
    128bitの戻り値の場合は上位64bitがrdx,下位64bitがraxに。浮動小数点の128bitの場合は上位64bitがxmm0,下位64bitがxmm1に入る。

  2. レジスタの退避
    呼び出し先退避レジスタはrbx,rbp,rsp,r12-r15の合計7つのレジスタ。呼び出されたプロシジャー自身が退避・復旧する。関数の中でこれらのレジスタを使用する場合は関数内で元に戻す必要がある。呼び出し元退避レジスタは上の7つ以外のレジスタであり、関数を呼び出す側が呼び出し前に退避し、呼び出し後に復旧する。

  3. システムコール
    raxにシステムコール番号、引数を以下のようにセットしてsyscallを呼ぶ。6つ以上の引数を取ることはできない。システムコール番号は/usr/include/x86_64-linux-gnu/asm/unistd_64.hで定義されている。

第一引数 第二引数 第三引数 第四引数 第五引数 第六引数
rdi rsi rdx r10 r8 r9

関数呼び出しとレジスタが違うのはsyscall命令がrcxとr11を書き変えるため。

  1. レッドゾーン
    これはwindowsには存在しない概念。レッドゾーンはスタックポインタの下に配置される最適化のための領域(128byte)で、この範囲はスタックポインタの変更なしで使用できる。