My friends, my life, my style - James S.F. Hsieh

3/17/2009

x64 Part 2: Calling convention 小記

以下是 MSDN 收集來的資訊 用來說明 Calling convention 之間的差異

下表用來說明暫存器在 Windows X64 下函式呼叫的使用條件

以下是 Windows x64 下的 Stack layout, Function B 呼叫 Function C 時, 必須將 Fun B 所規定的引數設定於暫存器與推入堆疊, 當 Fun B 是用 asm "call Fun C" 時, 該指令會將對應的返回位址也推入堆疊. 值得一提的是 Windows x64 有下述的數個規定:

  1. 我們所知, RCX, RDX, R8, R9 可以用來傳遞前四個整數型態的引數, 當然這些引數必須對其 1, 2, 4, 8 個 bytes 對齊, 否則將以 reference 的方式傳遞, 而 MMX0~MMX3 可以用來傳遞浮點數類型的引數. 而 16 bytes 的數值引數也必須以 reference 的方式傳遞.
  2. 呼叫函數不管是否傳遞引數, 呼叫端都會固定推入 32 個 Bytes 做為 RCX ~ R9 的堆疊暫存空間. 所以每次呼叫函數都至少會推入 32 Bytes 做為 Spilling space 或稱 shadow space, 和 8 Bytes 的返回位址.
  3. 函數呼叫堆疊清除的責任是由被呼叫這來負責, 傳回值如果是整數則放在 RAX, 是浮點數或是 16 bytes 的數值則放在 MMX0, 對於非 1, 2, 4, 8, 16 bytes 對齊的傳回值則以指標方式傳遞, 指標放置於 RAX.
  4. volatile 類型的暫存器可以隨意由函數使用, 當然有些用來傳遞引數.
  5. non-volatile 類型的暫存器可以以隨意由函數使用, 但是 return 時必須還原原本的數值.
  6. Stack 空間的配置 (用來傳遞引數. non-volatile 暫存器 或是存放區域變數) 必須對齊 16 Bytes.

Argument Passing and Naming Conventions, Overview of x64 Calling Conventions, win64 Structured Exception Handling, The history of calling conventions, part 5: amd64, Moving to Windows Vista x64