2010-01-15 97 views
5

我必須做一個接口(比如,一個包裝器),允許從X86_64彙編代碼使用他的調用約定調用C函數,與其他調用約定。最好的事情將是漂亮的「編譯器獨立」(正確修改封裝),所以我正在尋找一些東西,把寄存器/堆棧的東西放在編譯器上。我已經在這裏看到:Custom calling convention for P/Invoke and C#,它接近我所要做的。目前,我正在使用GCC,但歡迎來自其他編譯器的提示!自定義X86_64調用約定到C函數調用

所以,這裏的東西,對這個問題的最佳視圖(自定義編碼約定是怪):

pushq %r11 # saves r11 for call 
movq 64bits_address %r11 # move a 64 bits address that points on a data structure 
callq *8(%r11) # calls an address in the data structure 
popq %r11  # restores %r11 ; return value is in the structure 

我需要能夠調用「特殊」(包裝)C函數;這裏的工作將是調用其他C函數之間的調用。所以這個包裝需要找到%r11,保存所有的寄存器,並準備進一步調用堆棧。有沒有一個適當的方法來做到這一點在C(與一些內聯彙編)?

非常感謝

+0

Visual C++有一個'__declspec(naked)'修飾符,用於防止編譯器生成序言和結尾。 – 2010-01-15 10:38:55

+0

編譯x64目標(以及內聯彙編)時不支持__declspec(naked)。 – Andrey 2010-12-23 08:06:25

回答

3

有關調用約定,以及如何獲取文檔是傳遞給函數的參數(寄存器?哪些?什麼是堆棧等上)看看Agner Fog's document

然後,你可以看看libffi的源代碼,看看他們是如何做到的。

+0

感謝您的回答; 我不知道libffi,我要檢查這個,聽起來很棒。 – Matthieu 2010-01-15 10:48:10

+0

如果我是你,如果可能的話,我只會依賴libffi。它是穩定的,維護和處理許多角落案件 – 2010-01-15 10:51:37

+0

好吧,Agner霧的文件是非常有用的。但是libffi並不保存所有寄存器,特別是YMM寄存器(還沒有?)。順便說一句,我應該可以做一些與此相關的東西! 非常感謝。 – Matthieu 2010-01-15 15:31:59