我为Brainfuck编写了一个JITting VM。它需要创建一个可写的+可执行的内存区域(它是char*
,但不是用malloc
或new
创建的),它充满了机器操作码(在我的情况下为x64) ,然后在将char*
转换为函数指针后调用。新创建的函数有参数。即,内存指针和其他一些内部事物。
它有效,但它假定某个寄存器映射。一段时间之前,这种映射已经发生了变化,因为我将调用的代码更改为char*
,并且编译器认为它可以更好地与其他寄存器一起工作。所以我不得不改变代码生成方案。
我担心我会做一些会让编译器再次更改它的东西,或者更糟糕的是,使用堆栈,我不知道如何从(还)中提取参数。
所以我需要:
我正在使用gcc 4.8.2。
答案 0 :(得分:1)
当你调用一个函数时,编译器通常不会选择放置调用参数的位置。这由ABI决定。如果您的宿主程序是用C ++编写的并且在Linux / x86-64机器上运行,它通常会发出符合SysV ABI中描述的调用约定的代码,该约定包含以下参数传递规则:
如果类是INTEGER,则序列%rdi的下一个可用寄存器, 使用%rsi,%rdx,%rcx,%r8和%r9。
值得注意的是,INTEGER类也包含指针参数。
这里的底线是你的jitted代码应该能够从上面列出的寄存器中挑选出它的参数。如果仍然无法正常工作,我怀疑您可能错误地编写了指令。尝试从GDB中查看反汇编。
(*)如果无法从翻译单元外部调用函数,则可以为编译器提供更大的灵活性。