我正在编写一个程序,该程序在汇编中需要一个功能。将汇编函数封装在C ++类中将非常有帮助,因此将其自身的数据隔离开,并且我可以创建多个实例。
如果我创建一个类并从C ++方法调用一个外部函数,则该函数将是可重入的,即使它具有自己的堆栈和堆栈框架中的局部“变量”。
是否有某种方法可以使汇编函数成为C ++方法(也许使用名称修饰),因此该函数在汇编中实现,但原型在C ++类中声明?
如果不可能,是否有某种方法可以创建汇编函数的多个实例(通常),尽管它不是该类的一部分?诸如在内存中克隆该函数并调用它之类的东西,显然是使用可重定位代码(如果需要,为变量和数据添加增量位移)...
谢谢!
答案 0 :(得分:3)
我正在编写一个需要汇编功能的程序。
然后,根据定义,您的程序变少了portable。并且取决于您的C ++实现和操作系统的calling conventions和ABI。
然后使用某些特定于编译器的功能是一致的(便携式标准C ++ 11中没有这些功能,例如n3337中的功能)。
然后,我的建议是利用GCC扩展程序集。阅读有关using assembly language with C的章节(当然,它也适用于C ++)。
通过直接将扩展的asm
嵌入C ++成员函数中,可以避免调用某些函数的麻烦。可能您的汇编代码确实很短并且可以快速执行。因此最好将其嵌入C或C ++函数中,以避免函数调用序言和结语的代价。
注意:在2019年,花大量精力编写大型汇编代码是没有经济意义的:大多数优化的编译器所产生的汇编代码要比合理的程序员(在合理的时间内)更好。因此,您有动力在较大的C ++或C函数中使用 small 汇编代码块。
答案 1 :(得分:1)
是的,可以。将其定义为将所有args(包括隐式this
指针)传递给外部函数的内联包装器,或者找出名称修饰符以为asm中的函数入口点定义正确的符号。>
包装方式的示例:
extern "C" int asm_function(myclass *p, int a, double b);
class myclass {
int q, r, member_array[4];
my_method(int a, double b) { return asm_function(this, a, b); }
};
对于x86-64,my_method
的独立定义将只是jmp asm_function
,这是一个尾声,因为args相同。因此,在内联之后,您将拥有call asm_function
而不是call _Zmyclass_mymethodZd
或任何实际的名称修饰。 (我做了)。