title: Visual C++ inline x86 assembly: Accessing "this" pointer
body: <p>According to the MSDN documentation the "this" pointer is stored in ECX when using the default <a href="http://msdn.microsoft.com/en-us/library/ek8tkfbw%28v=vs.100%29.aspx">__thiscall</a> calling convention for class functions. Despite this certainly being the case when translating regular C++ code I have encountered a problem when trying to access "this" with inline assembly.</p>
  
  <p>Here's the test program:</p>
  
  <pre><code>#include &lt;cstdio&gt;
  
  class TestClass
  {
      long x;
  
      public:
          inline TestClass(long x):x(x){}
  
      public:
          inline long getX1(){return x;}
          inline long getX2()
          {
              _asm
              {
                  mov eax,dword ptr[ecx]
              }
          }
  };
  int main()
  {
      TestClass c(42);
  
      printf("c.getX1() = %d\n",c.getX1());
      printf("c.getX2() = %d\n",c.getX2());
  
      return 0;
  }
  </code></pre>
  
  <p>The two Get functions are translated like this:</p>
  
  <pre><code>?getX1@TestClass@@QAEJXZ (public: long __thiscall TestClass::getX1(void)):
    00000000: 8B 01              mov         eax,dword ptr [ecx]
    00000002: C3                 ret
  
  ?getX2@TestClass@@QAEJXZ (public: long __thiscall TestClass::getX2(void)):
    00000000: 8B 01              mov         eax,dword ptr [ecx]
    00000002: C3                 ret
  </code></pre>
  
  <p>I think it's safe to say that these two functions are identical. Nevertheless, here's the output from the program:</p>
  
  <pre><code>c.getX1() = 42
  c.getX2() = 1
  </code></pre>
  
  <p>Obviously "this" is <em>not</em> stored in ECX when the second Get function is invoked, so my question is: How do I ensure that class functions containing inline assembly follow the calling convention and/or are invoked the same way as regular/non-inlined functions?</p>
  
  <p>EDIT: The main function is translated like this:</p>
  
  <pre><code>_main:
    00000000: 51                 push        ecx
    00000001: 6A 2A              push        2Ah
    00000003: 68 00 00 00 00     push        offset $SG3948
    00000008: E8 00 00 00 00     call        _printf
    0000000D: 83 C4 08           add         esp,8
    00000010: 8D 0C 24           lea         ecx,[esp]
    00000013: E8 00 00 00 00     call        ?getX2@TestClass@@QAEJXZ
    00000018: 50                 push        eax
    00000019: 68 00 00 00 00     push        offset $SG3949
    0000001E: E8 00 00 00 00     call        _printf
    00000023: 33 C0              xor         eax,eax
    00000025: 83 C4 0C           add         esp,0Ch
    00000028: C3                 ret
  </code></pre>