我遇到了一个非常特殊的问题。 对于VM我需要从该指令的功能拷贝代码到一个UBYTE数组,然后执行该阵列(该TECHNIC类同于GCC内嵌宏VM),基本上它的工作原理是这样的:D内联汇编程序:函数调用出错
__gshared void * sp = null, sb = null; //stack pointer and stack base
__gshared void add() //the function is just there to access the instruction code
{
asm{db "INSTRUCTIONCODESTART";} //this is a key to know where the instruction code starts
//instruction code here (sample instruction add, pops 2 values from the stack and pushes its result)
sp += 4;
*cast(uint*)sp += *cast(uint*)(sp - 4);
asm{db "INSTRUCTIONCODEEND";} //this is a key to know where instruction code ends
}
在Init方法,每个指令代码都有自己的缓冲区,缓冲区中的每个字节都是INSTRUCTIONCODESTART和INSTRUCTIONCODEEND键之间的字节。我通过windows VirtualProtect调用使该数组可执行。到目前为止,一切都按预期工作,但是当我试图做一个函数调用作为指令时,我会得到一个错误。
__gshared void testcall(){}
__gshared void call()
{
asm{db "INSTRUCTIONCODESTART";} //this is a key to know where the instruction code starts
//instruction code here (just calls a D function)
testcall(); //this somehow throws an error
asm{db "INSTRUCTIONCODEEND";} //this is a key to know where instruction code ends
}
顺便说一句我用下面的代码测试说明
void instructiontest()
{
uint dummy;
ubyte[] buf = getFunctionCode(&add) ~ 0xC3; //gets code of instruction, appends 0xC3 at it ("ret" instruction, for test purposes only to see if it returns to the D code without errors)
VirtualProtect(cast(void*)buf, buf.length, PAGE_EXECUTE_READWRITE, &dummy); //makes it executeable
dummy = cast(uint)&buf[0];
asm
{
call dummy[EBP];
}
print("instruction worked without errors!");
}
到目前为止,每一个简单的指令(添加,MUL子,push0,push1,...)的作品,但如果我尝试通过函数调用来获取指令的代码,它会抛出一个错误
我会很高兴,非常感谢任何帮助。 (顺便说一句,我需要在指令函数调用为了让脚本语言与沟通d)
仅供参考:'__gshared'对功能,只有变量没有影响。 – 2012-07-15 12:14:12