2013-05-25 38 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

相關問題