coneagoe 发表于 2011-08-11 16:53

gcc inline-assembly问题

Hi,

我最近在做一个mocking库的移植,GAS我不是很熟悉。编译时有问题,请教各位大侠,谢谢。

源码:#include "Mocker.h"
   
    namespace MockItNow
    {
      int g_jumpAddress;
   
      extern "C" void __declspec(naked) _penter()
      {
            // Prologue
            __asm
            {
                push ebp
                mov ebp, esp
                sub esp, __LOCAL_SIZE
                push eax
                push ebx
                push ecx
                push edx
            }
   
            int* framePointer;
            __asm mov dword ptr , ebp
   
            int targetPointer;
            __asm mov , ecx
   
            {
                int callingFunctionAddress = (*(framePointer + 1) - 5);
   
                if (Mocker::IsAlive() == false || Mocker::Instance().ShouldStubFunction(callingFunctionAddress, targetPointer) == false)
                {
                  // Standard epilogue. Don't stub the function
                  __asm
                  {
                        pop edx
                        pop ecx
                        pop ebx
                        pop eax
                        mov esp, ebp
                        pop ebp
                        ret
                  }
                }
   
                Mocker::Instance().SetCurrentFunctionAddress(callingFunctionAddress);
   
                g_jumpAddress = Mocker::Instance().GetFunctionJumpAddress();
   
                // Non-standard epilogue. Stub the function
                __asm
                {
                  pop edx
                  pop ecx
                  pop ebx
                  pop eax
                  mov esp, ebp
                  pop ebp
                  add esp, 4
                  jmp g_jumpAddress
                }
            }
      }
    }我修改的:1 #include "Mocker.h"
      2
      3 using namespace MockItNow;
      4
      5 int g_jumpAddress;
      6 int * g_pFrame;
      7 int g_targetAddress;
      8
      9 __attribute__((no_instrument_function))
   10 void __cyg_profile_func_enter(void * pFun, void * pCallSite);
   11
   12 __attribute__((no_instrument_function))
   13 void __cyg_profile_func_exit(void * pFun, void * pCallSite);
   14
   15 void __cyg_profile_func_enter(void * pFun, void * pCallSite)
   16 {
   17   // Prologue
   18   asm volatile ("pushl %ebp\n\t"
   19         "movl %esp, %ebp\n\t"
   20         "subl __LOCAL_SIZE, %esp\n\t"
   21         "pushl %eax\n\t"
   22         "pushl %ebx\n\t"
   23         "pushl %ecx\n\t"
   24         "pushl %edx");
   25
   26   asm volatile ("movl %ebp, $g_pFrame\n\t"
   27         "movl %ecx, g_targetAddress");
   28      
   29   {   
   30         int callingFunctionAddress = (*(g_pFrame + 1) - 5);
   31         
   32         if(Mocker::IsAlive() == false || Mocker::Instance().ShouldStubFunction(callingFunctionAddress, g_targetAddress) == false)
   33         {   
   34             // Standard epilogue. Don't stub the function
   35             asm volatile ("popl %edx\n\t"
   36               "popl %ecx\n\t"
   37               "popl %ebx\n\t"
   38               "popl %eax\n\t"
   39               "movl %ebp, %esp\n\t"
   40               "popl %ebp\n\t"
   41               "ret");
   42         }
   43
   44         Mocker::Instance().SetCurrentFunctionAddress(callingFunctionAddress);
   45
   46         g_jumpAddress = Mocker::Instance().GetFunctionJumpAddress();
   47
   48         // Non-standard epilogue. Stub the function
   49         asm volatile ("popl %edx\n\t"
   50             "popl %ecx\n\t"
   51             "popl %ebx\n\t"
   52             "popl %eax\n\t"
   53             "movl %ebp, %esp\n\t"
   54             "popl %ebp\n\t"
   55             "addl $4, %esp\n\t"
   56             "jmp g_jumpAddress");
   57   }
   58 }
   59
   60
   61 void __cyg_profile_func_exit(void * pFun, void * pCallSite)
   62 {
   63   // nothing
   64 } 编译报错:    make: Entering directory `/cygdrive/d/tools/test/MockItNow2/MockItNow'
    /bin/sh ./libtool--tag=CXX   --mode=compile g++ -DHAVE_CONFIG_H -I.   -g -O2 -MT Thunk.lo -MD -MP -MF .deps/Thunk.Tpo -c -o Thunk.lo `test -f 'Win32/Thunk.cpp' || echo './'`Win32/Thunk.cpp
    libtool: compile:g++ -DHAVE_CONFIG_H -I. -g -O2 -MT Thunk.lo -MD -MP -MF .deps/Thunk.Tpo -c Win32/Thunk.cpp-DDLL_EXPORT -DPIC -o .libs/Thunk.o
    /tmp/ccRfDyJZ.s: Assembler messages:
    /tmp/ccRfDyJZ.s:57: Error: operand type mismatch for `mov'
    make: *** Error 1
    make: Leaving directory `/cygdrive/d/tools/test/MockItNow2/MockItNow'
    make: *** Error 2

EricFisher 发表于 2011-08-15 12:48

#   /tmp/ccRfDyJZ.s: Assembler messages:
#   /tmp/ccRfDyJZ.s:57: Error: operand type mismatch for `mov'

先用 -save-temps 选项把.s文件保存下来,然后看看57行是什么。

coneagoe 发表于 2011-08-17 18:40

回复 2# EricFisher
找到问题了。
asm volatile ("movl %ebp, $g_pFrame\n\t"
      "movl %ecx, g_targetAddress");
应该改为:
asm volatile ("movl %ebp, (g_pFrame)\n\t"
      "movl %ecx, g_targetAddress");
页: [1]
查看完整版本: gcc inline-assembly问题