Allexj
Allexj

Reputation: 1487

Who and how generate the virtual/logical addresses? Confusion if it's the compiler, the linker, the loader

I know that when I compile a program and then I inspect with objdump, I have addresses. These are relative addresses.

But if it's a C program and I printf with %p a pointer, that is a virtual/logical address. Who generates this? Is that the loader?

If yes, why do I need that a loader does this? Isn't it sufficient a relative address (generated by compiler) and then MMU just adds the program base offset in real memory to reach the physical address? Why a virtual address is needed and a relative insufficient?

Also, virtual addresses should serve to create an illusion to process to be the only one in memory and to be contiguously allocated. I can imagine this with relative (generated by compiler) addresses, but I can't imagine with virtual/logical (generated by loader) addresses... How can loader achieve to put program code in contiguous portion of virtual memory? Isn't virtual memory used by other programs in separate portions? Or can it happen that two completely different programs have same virtual/logical addresses ?

Also, last doubt: why in lot of places online it's written that "virtual/logical address are generated by CPU"..... it's not true..... it's done by the OS, so why it's written everywhere? am I missing something?

Upvotes: 0

Views: 39

Answers (1)

user3344003
user3344003

Reputation: 21617

The answer is that there are several answers, depending upon how the memory was allocated or used.

Case I:

The linker defines the initial state for the process. If you print the address of a static location, that comes from the linker.

Case II:

This can be complicated by the fact that shared libraries (also created by a linker) can usually be loaded to different locations. In that case, your address is defined by a combination of the linker (offset) and loader.

It can also be complicated by the fact that some operating systems will load programs in different locations for security. In that case, your address is defined by a combination of the linker and loader. The link

It is for these two reasons that we strive for "position independent code" that is not tied to specific memory locations.

However, there are cases where specific memory locations are require or come from code that it not position independent.

static int a, *b=&a ;

Here the initialization of "b" requires knowing the location of "a." Some systems have work-arounds for this that allow the loader to initialize "a" at load time so that the code can still be position independent.

Case III:

If you are printing the location of dynamic memory, that typically comes from the operating system at run time.

int *x = malloc (sizeof (*x)) ;

Case IV:

If you are printing the location of stack, that is determined at run time with backup that can come from either the linker or the operating system at run time. In system systems the linker defines the stacks. In others the operating system defines the stacks.

Upvotes: 0

Related Questions