Compiler determines address of every variables and methods while compiling source code not while executing the binary (it is applicable to virtual methods and dynamic link libs as well). Now the question is when address is determined at compile time, how run time binding works?
Here is the answer:
Whenever a method is called, compiler puts machine level code (‘call’ instruction in assembly level language) and supplies method’s address to call that method. Let’s take an simple example to understand this:
class test {
public:
          void compile_time_binding_method()
{ printf("\nIn compile_time_binding_method() method"); }
virtual void run_time_binding_method()
{ printf("\nIn compile_time_binding_method() method"); }
};
Here, the ‘test’ class contain a virtual method ‘run_time_binding_method()’ and a non-virtual method ‘compile_time_binding_method()’.
Let’s create an object, its reference and a pointer to point to the created object:
test a; // Created a object of test class
test &refA = a;  // Reference of object ‘a’
test *ptrA = &a; // Pointer of object ‘a’
Let’s call methods using object:
What do think calling a virtual method via its object will be a run time binding? If your answer is no, you are correct. When any method is called using its object, compiler is sure about the method to call. So dynamic binding/call is not at all required here even if a virtual method is being called. You can verify this by reviewing generated dis-assembly code.
a.compile_time_binding_method();
lea         ecx,[a]                                                      // Dis-assembly code
call        test::compile_time_binding_method (41118Bh)
a.run_time_binding_method();
lea         ecx,[a]                                                      // Dis-assembly code
call        test::run_time_binding_method (4110EBh)
In above generated dis-assembly code, we can see that the address of both the methods are hard coded (address determined by compiler while compiling the source code) to resolve the call. This hard coded address will never change (unless you modify and re-compile the source code) in the binary. Such binding/linking is known as static binding/linking (or compile time binding).
These calls are static calls because address is hard coded with machine code generated by compiler (same as ‘call
Let’s call methods using its pointer:
For non-virtual methods:
ptrA->compile_time_binding_method();
mov      ecx,dword ptr [ptrA]
call        test::compile_time_binding_method (41118Bh)
ptrA->run_time_binding_method();
mov         eax,dword ptr [ptrA] //getting object's address
mov         edx,dword ptr [eax]  //getting  VTABLE's address 
mov         esi,esp
mov         ecx,dword ptr [ptrA]
//The following line will gets the address of
//run_time_binding_method() from VTABLE 
mov         eax,dword ptr [edx] 
call            eax                            // will call run_time_binding_method
cmp         esi,esp
call        @ILT+370(__RTC_CheckEsp) (411177h)
Let’s call methods using its reference:
As reference is nothing but an implicit pointer to the object, the method calls via reference is same as method calls via pointer:
refA.compile_time_binding_method();
mov      ecx,dword ptr [refA]
call        test::compile_time_binding_method (41118Bh)
refA.run_time_binding_method();
mov         eax,dword ptr [refA]
mov         edx,dword ptr [eax]
mov         esi,esp
mov         ecx,dword ptr [refA]
mov         eax,dword ptr [edx]
call        eax 
cmp         esi,esp
call        @ILT+370(__RTC_CheckEsp) (411177h)
As I am not an author by profession, I might not have explained it in a best way J. Please help me make it best by raising your question/doubt.
 
