我有一个相当特殊的问题:在 C/++ 中是否可以指定函数的位置(因为我确信问题在两种语言中都是相同的)?为什么?我有一个非常大的函数指针列表,我想消除它们。
(当前)这看起来像这样(重复一百万次,存储在用户的 RAM 中):
struct {
int i;
void(* funptr)();
} test;
因为我知道在大多数汇编语言中,函数只是“goto”指令,所以我有以下想法。是否可以优化上述构造,使其看起来像这样?
struct {
int i;
// embed the assembler of the function here
// so that all the functions
// instructions are located here
// like this: mov rax, rbx
// jmp _start ; just demo code
} test2;
最后,内存中的内容应如下所示:一个包含任意值的 int,后跟 test2 引用的函数的汇编代码。我应该能够像这样调用这些函数: ((void(*)()) (&pointerToTheStruct + sizeof(int)))();
您可能会认为我以这种方式优化应用程序是疯狂的,而且我无法透露有关其功能的更多细节,但如果有人对如何解决这个问题有一些指导,我将不胜感激。 我不认为有一个标准的方法,所以任何通过内联汇编器/其他疯狂的东西来做到这一点的黑客方法也值得赞赏!
最佳答案
您真正需要做的唯一一件事是让编译器知道您想要在结构中的函数指针的(常量)值。然后,编译器将(大概/希望)内联该函数调用,只要它看到它通过该函数指针调用:
template<void(*FPtr)()>
struct function_struct {
int i;
static constexpr auto funptr = FPtr;
};
void testFunc()
{
volatile int x = 0;
}
using test = function_struct<testFunc>;
int main()
{
test::funptr();
}
Demo - 优化后没有 call
或 jmp
。
目前还不清楚 int i 的意义是什么。请注意,这里的代码在技术上并不是“直接在 i
之后”,但更不清楚您期望结构体的实例是什么样子(是其中的代码还是在某种程度上是“静态”的?我觉得您对编译器实际生成的内容存在一些误解......)。但考虑一下编译器内联可以帮助您的方式,您可能会找到您需要的解决方案。如果您担心内联后可执行文件的大小,请告诉编译器,它会在速度和大小之间进行折衷。
关于c++ - 将函数汇编代码嵌入结构中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54150545/