我如何知道将映射到哪些寄存器函数参数?

How do I know what registers function parameters will be mapped on?

我已经为 Brainfuck 编写了一个 JITting VM。它需要创建一个可写+可执行的内存区域(它是一个 char*,但不是用 mallocnew 创建的),它充满了机器操作码(在我的例子中是 x64) ,然后在将 char* 转换为函数指针后调用。新创建的函数有参数。即,内存指针和其他一些内部的东西。

它可以工作,但它假定了特定的寄存器映射。那个映射已经改变了,曾经有一段时间,因为我将调用周围的代码更改为 char* 并且编译器决定它可以更好地与其他寄存器一起工作。所以我不得不改变代码生成方案。

恐怕我可以做一些会让编译器再次更改它的事情,或者更糟的是,使用堆栈,我还不知道如何从中提取参数。

所以我需要:

我正在使用 gcc 4.8.2。

当您调用一个函数时,编译器通常*无法选择将调用参数放在何处。这是由 ABI. If your host program is written in C++ and runs on a Linux/x86-64 machine, it will generally emit code that conforms to the calling convention described in the SysV ABI 规定的,其中包含以下参数传递规则:

If the class is INTEGER, the next available register of the sequence %rdi, %rsi, %rdx, %rcx, %r8 and %r9 is used.

值得注意的是,INTEGER class 也包含指针参数。

这里的底线是你的 jitted 代码应该能够从上面列出的寄存器中选择它的参数。如果这仍然无法正常工作,我怀疑您可能对指令进行了错误的编码。尝试从 GDB 查看反汇编。

(*) 好吧,如果不能从翻译单元外部调用该函数,编译器可能会提供更多的灵活性。