2010-01-15 56 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