Function Calls, Part 4 (What Exactly Is "this"?)

by Kiran Sanjeeva

Learn about a dissasembly view of function calls, and decipher the __thiscall calling convention.

Introduction and Series Recap

  • In Part 1, you looked at the basic structure of code generated surrounding a function call.
  • In Part 2, you looked at calling conventions and studied the code generated for two popular calling conventions, __stdcall and __cdecl.
  • In Part 3, you looked at stack frame and studied the positioning of local variables and function arguments in the frame.

In this article, you will explore a slightly more complex data type, class. You may wonder what any of this has got to do with functions. Suffice it to say that, for now, classes can have member functions, which after all are functions. And, because you are on the topic of functions, take a look at them, a little closer look.


I will not go into what classes are and things like that. I assume readers would be familiar with this already. In this part, you will concern yourself with the member functions of a class.

Member functions of a class are similar to the non-member functions, in that they have a return type associated with them; they could take arguments and they could have local variables. Where member functions will differ from their other counterpart—in other words, the non member function types—is in the fact that, apart from the local variables, the member functions have access to the object's data.

Here's an example:

int result1 = funcA(1,2);
classA objA;
int result2 = objA.memberFuncA(1,2)

Looking at the code above, you see the striking similarity in how the function is called in the two cases, member function and non-member function. In fact, that is the case. Member function calls are in fact normal function calls. So, everything I talked about in the earlier parts about argument passing via stack, return value passing, pushing of return address on the stack, all work exactly the same way.

In case of a member function call, objA. indicates that the memberFuncA could access objA object's data. How does this work? How does memberFuncA code know what the objA's data is? It is not passed in as an argument, as you can see. Does it mean that the compiler is doing something silently and passing in all the objA's data as arguments, or perhaps, the compiler is passing in the objA's address as an argument to memberFuncA... or is it something else?

Digging into Disassembly

You have the background from the earlier parts on how to analyze this. Start digging in now.

So, What Exactly Is this?

Often, you might have come across code where you would have seen this being used. What exactly is this? It seems like a member variable (because, it can be used only within the scope of the class' member functions), yet, you don't declare it within the class declaration. Again, so is it something that compiler silently adds as a member variable? It turns out, it is none of these. It is simply a reference to the address to the object, and as you just saw, it is what ECX contents are when the function has just entered, or, subsequent to the stack frame preparation, it is the [EBP-4] contents. To confirm this, use the code below, put a breakpoint on line 12, and go to disassembly. Look what is being pushed as the parameter to funcCheckThis.



As an exercise, I suggest you might want to change the data members of the class, add virtual functions, and see how the generated code differs. Also, note that __thiscall is the default. One can very well force the compiler to use __cdecl or __stdcall for member functions too. For example, try out a mix like this:

class ClassA
   void __stdcall Expand()
   int m_nData;

int _tmain(int argc, _TCHAR* argv[])
   ClassA objA;
   return 0;

Check out the disassembly of the _tmain function and note how, because Expand has the __stdcall convention, ECX is not used, but the objA address is pushed on the stack as if it were an argument. So, no matter what calling convention is used, the stack is again central to how data is passed to a function, be it function arguments, local variables, or the address of the object, in case of member functions.


To summarise, this is what you have learned so far:

  • You learned about the __thiscall calling convention.
  • You learned how the ECX register is used in __thiscall calling conventions to pass in the object address to the callee.
  • Finally, you learned what 'this' really means.


This article was originally published on Thursday Feb 14th 2008
Mobile Site | Full Site