1

I have the following code:

class Base {
public:
int x,y;
Base() { x=10; y=20; }
virtual void myfunction() { }
};

int main() {
Base *b = new Base();
return 0;
}

The disassembly gives me something like:

push 0Ch                ; size of Base
call j_<some giberrish> ; IDA gives the comment "operator new(uint)"
add esp, 4              ; function epilogue
mov [ebp+var_E0], eax

A few lines later you have the constructor being called.

mov ecx, [ebp+var_E0]
call j_Base__Base
mov [ebp+var_F4], eax
  • At first I had thought that var_E0 would contain the pointer to the instance, but now I'm pretty sure that var_F4 does as it contains the return value of the constructor.
  • In that case, what does var_E0 contain at all? Why is it moved into ecx before the constructor is called?
user1354557
  • 2,413
  • 19
  • 29

3 Answers3

2

It's some internal variable for a compiler generated temporary.

When you write new Base, the compiler generates a call to the global operator new function, then calls the constructor on the returned address. Apparently, your compiler saves the address returned from operator new in memory, rather than keeping it in a register.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
2

Visual C++ uses an internal convention where constructors return the pointer to the object instance (by C++ standard, constructors don't have a return value). So in your case both var_E0 and var_F4 hold the instance pointer.

Check my article for more details on how Visual C++ implements C++.

Igor Skochinsky
  • 24,629
  • 2
  • 72
  • 109
1

This is almost certainly a debug build you're looking at and debug builds are very conservative with what they do. Creating an object is a two stage process: allocate memory and then construct the object. Your compiler is putting the allocated memory pointer into a temporary variable. If you build an optimised version, this temporary variable won't be stored since that introduces an unnecessary overhead (writing/reading RAM).

Skizz
  • 69,698
  • 10
  • 71
  • 108
  • 1
    Just to clarify, the first call allocates memory and not the call to j_Base__Base, correct? Thanks! –  Jun 22 '11 at 08:48
  • @eQuiNoX - Like Skizz says, the compiler must do this in separate steps, allocate memory and then construct the object. In the worst case, when construction fails, it must also call `operator delete` to release the memory. That's a good reason for saving the pointer. :-) – Bo Persson Jun 22 '11 at 09:22