-2
我有这样的代码块:没有这样的指令.. GCC x86_64的
void CallAnyFunc(void *pfn, const std::vector<char> &arguments, CLR_DataType returnType, AnyFuncReturn &returnValue)
{
int i4;
float r4;
double r8;
long int i8;
char* pStack;
const char* i = arguments.empty() ? NULL : &*arguments.begin();
const char* end = i + arguments.size();
// Reserve the space on the stack
// This is equivalent (in some sense) to 'push' all the parameters into the stack.
// NOTE: Don't just subtract the stack pointer, better to call _alloca, because it also takes
// care of ensuring all the consumed memory pages are accessible
#ifdef PLATFORM_WINDOWS
_alloca(arguments.size());
#else
alloca(arguments.size());
#endif
_asm {
mov pStack, esp
};
// Copy all the parameters into the stack
// NOTE: Don't use the memcpy function. Because the call to it
// will overwrite the stack (which we're currently building)
while (i != end)
*pStack++ = *i++;
switch (returnType)
{
case DATATYPE_R4:
{
// Call your function
_asm {
call pfn
fstp r4
}
returnValue.r4 = r4;
} break;
case DATATYPE_R8:
{
// Call your function
_asm {
call pfn
fstp r8
}
returnValue.r8 = r8;
} break;
case DATATYPE_U8:
case DATATYPE_I8:
{
// Call your function
_asm {
call pfn
mov i8, eax
}
returnValue.i8 = i8;
} break;
default:
{
_asm {
call pfn
mov i4, eax
};
returnValue.i4 = i4;
}
}
}
基本上它是一个桥进入呼叫CLR微点网。
当我与设有xcode中的gcc编译我得到:
nmfi/nmf_call.cpp:153:no such instruction: `movlq %esp, -96(%rbp)'
nmfi/nmf_call.cpp:164:indirect call without `*'
nmfi/nmf_call.cpp:175:indirect call without `*'
nmfi/nmf_call.cpp:187:indirect call without `*'
nmfi/nmf_call.cpp:190:no such instruction: `movlq %eax, -88(%rbp)'
nmfi/nmf_call.cpp:197:indirect call without `*'
其中线153 = MOV的pstack后线,尤指 和线190 =之后线returnValue.i8 = I8是概率实际上MOV i8的,EAX
...
这段代码利用工作得很好。我计算出的变化是因为x86_64,但在解决如何正确编写“mov”以便可以进行汇编时遇到问题。
...
相关的编译器选项:
CC := g++
CFLAGS := -c -DLITTLE_ENDIAN=1 -DGCC_V4_2 -fasm-blocks \
-DVERSION_MAJOR="4" -DVERSION_MINOR="2" -DVERSION_BUILD="1" -DVERSION_REVISION="0" \
-DOEMSYSTEMINFOSTRING='"OSXBOI"'
# -DMAC -fvisibility=hidden -fvisibility-inlines-hidden
AR := ar
ARFLAGS := rs
ifeq (,$(findstring Debug,$(CONFIG)))
CFLAGS += -O3 -DNDEBUG
else
CFLAGS += -g -D_DEBUG
endif
任何提示?
这里是修订的代码,这是未经测试的,但它编译。
void CallAnyFunc(void *_pfn, const std::vector<char> &arguments, CLR_DataType returnType, AnyFuncReturn &returnValue)
{
int i4;
float r4;
double r8;
long int i8;
typedef void (*PFN)();
PFN pfn = (PFN)_pfn;
char* pStack;
const char* i = arguments.empty() ? NULL : &*arguments.begin();
const char* end = i + arguments.size();
// Reserve the space on the stack
// This is equivalent (in some sense) to 'push' all the parameters into the stack.
// NOTE: Don't just subtract the stack pointer, better to call _alloca, because it also takes
// care of ensuring all the consumed memory pages are accessible
#ifdef PLATFORM_WINDOWS
_alloca(arguments.size());
#else
alloca(arguments.size());
#endif
#ifdef X86_64
_asm {
mov pStack, rsp
};
#else
_asm {
mov pStack, esp
};
#endif
// Copy all the parameters into the stack
// NOTE: Don't use the memcpy function. Because the call to it
// will overwrite the stack (which we're currently building)
while (i != end)
*pStack++ = *i++;
switch (returnType)
{
case DATATYPE_R4:
{
// Call your function
_asm {
call *pfn
fstp r4
}
returnValue.r4 = r4;
} break;
case DATATYPE_R8:
{
// Call your function
_asm {
call *pfn
fstp r8
}
returnValue.r8 = r8;
} break;
case DATATYPE_U8:
case DATATYPE_I8:
{
#ifdef X86_64
// Call your function
_asm {
call *pfn
mov i8, rax
}
#else
_asm {
call *pfn
mov i8, eax
}
#endif
returnValue.i8 = i8;
} break;
default:
{
#ifdef X86_64
// Call your function
_asm {
call *pfn
mov i4, eax
}
#else
_asm {
call *pfn
mov i4, eax
}
#endif
returnValue.i4 = i4;
}
}
}
如果您正在构建64位代码,指针和long int的大小都将是64位。所以你可能想使用'rsp'和'rax'而不是'esp'和'eax'。 – Michael
你是对的。您是否对 “nmfi/nmf_call.cpp:170:间接呼叫没有任何提示?”“ ”,它对应于我相信的呼叫pfn。 也许我需要键入它作为一个函数指针? – iamacomputer
迈克尔,添加您的评论作为答案,我会给你的观点。 – iamacomputer