2013-05-25 39 views
-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; 
     } 
    } 
} 
+0

如果您正在构建64位代码,指针和long int的大小都将是64位。所以你可能想使用'rsp'和'rax'而不是'esp'和'eax'。 – Michael

+0

你是对的。您是否对 “nmfi/nmf_call.cpp:170:间接呼叫没有任何提示?”“ ”,它对应于我相信的呼叫pfn。 也许我需要键入它作为一个函数指针? – iamacomputer

+0

迈克尔,添加您的评论作为答案,我会给你的观点。 – iamacomputer

回答

0

如果您正在构建64位代码,指针和long int的大小都将是64位。您可能想要使用rsp而不是esp作为指针,以获取地址的所有位。

对于i8变量,你有一些选择:保持它作为一个long int(或更好,但int64_t),并使用rax代替eax。或者使其成为int32_t并继续使用eax

相关问题