What exactly is execution-time address binding? According to these two definitions:

Logical address: every memory address generated by the CPU.


Physical address: address which identifies uniquely a (real) memory cell.

my textbook (Operating systems concepts - Silberschatz, Galvin, Gagne) says that address binding at compile-time and load-time both generate identical logical and physical addresses, while execution-time binding produces different logical and physical address.
I've googled a lot, but every article which tries to explain this concept is not that clear. I can't understand what happens in the practice. I'll give you an example to let you understand what I mean:
The source code (high-level language instructions) contains symbolic addresses (like count) that are replaced (by the compiler) by:

physical addresses (compile-time binding) if the location in memory of the process can be known in advance (non-multi-programmed systems);
relocatable addresses (load-time binding) in the opposite case (most common).

Once the loader puts the obj into memory it replaces relocatable addresses with physical addresses (if there are any) and the program can be finally executed. The CPU can read and refer to physical addresses, so logical and physical addresses are the same. In both previous cases the binding is static: once loaded, the process can't be moved from one segment of memory to another.
In order to manage the memory in an efficient way, the system should be able to move a process from a location of the memory to another: this means that the process physical addresses can change at run-time. In order to implement this mechanism logical addresses and physical addresses must be different: logical addresses can change in an interval [0, max] and physical ones between [r, r+max], where r is the relocation register.
Does this mean that, in execution-time binding, the obj file contains virtual addresses ([0, max]), which are converted time by time by the system into physical ones? In other words, is true that the obj file doesn't contain any physical address (but a data structure of the OS keeps the informations about the process address binding) so each time the CPU reads (for example) ADD 100 105 the addresses 100 and 105 are converted into physical ones by the system (using MMU and data structures)?
Please correct any mistake I made, the textbook is not so clear.
Until the program is running, physical addresses make little (or no) sense: The instructions make reference to logical addresses.
While the program runs, the CPU maps logical addresses to physical addresses (they could be just exactly the same, or change e.g. by paging or just by relocation --- add the contents of a special register to each logical address to give the pysical address, used in some early machines to be able to place several programs tightly in memory and be able to move them around). If you look e.g. at the intel 8088/8086 (infamous CPUs for the original PC), it sports segment registers, so you can move say the stack around in RAM and the program doesn't care where it is.