What determines the memory address for global variables. Compiler or operating system?

Consider the program below.

int a = 0x45; int main() { int i = a; return 0; } ;; asm code call 0x401780 <__main> mov 0x402000,%eax // why does it allocate 0x402000 only for global 'a'? mov %eax,0xc(%esp) mov $0x0,%eax leave 

This is the equivalent build code generated by CodeBlocks on Windows / xp. I understand that 0x402000 is the address of the data segment. But is this memory location a hard-coded compiler?

I think that it is not hard-coded because this memory location may and may not be used by other applications.

As you know, the operating system allocates a Stack frame for local variables and returns the base addition of the stack frame. and local variables are accessed using the %esp and %ebp with an offset.

Does the operating system support the same thing for global variables? If he does the same, why is the value hard-coded?

 dw a 0x40; this directive allocates memory on data segment mov %ax,a; copies value of a to accumulator 

But as the compiler knows, "a" has a memory address of 0x402000 . If the compiler has a hardcoded value like 0x402000 , should it first verify that the address is not being used by another application?

If the operating system allocates memory for a datasegment, the memory address should be changed depending on applications and resources. Can someone explain what actually happens when I define global variables?

+5
source share
2 answers

As Professor Falken said, it depends on the compiler / system ... but ... Linux, Windows, Mac, popular / primary toolchains:

The compiler takes a high-level source and makes an assembly from it, the assembler turns it into an object. The object decides what relative addresses it can, but leaves the keys to the linker.

The linker ... links ... it takes objects, their binary blobs, organizes them into the binary address space that is mentioned, it selects addresses for things like global and functions. These are mostly places .text, .data and .bss.

Then there is mmu in the hardware, this greatly simplified life, you can, for example, compile each program, for example, the address 0x8000 as an entry point, and have many programs all running at 0x8000 at the same time. Because they all think that they are at this address, because they are in the virtual address space on the virtual side of mmu. On the physical side, they all actually live at different addresses, but in general, only the operating system should take care of this.

Therefore, compilers today usually place functions in the order in which we wrote them in the source code in the object, in the .data and .bss files that they sometimes rebuild. Usually linkers work the way they are told, and who tells them? Ultimately, we programmers, but the tool binding provided to you has default values ​​(for example, automatic assembly of compiled code into an object and automatic binding), including boot code and default linker script. This default linker script for this compiler for this target operating system is configured according to the rules of this operating system.

The above is what you usually see with gcc and other primary compilers for the leading windows, mac and * nix operating systems. This does not mean that there arent toolchains that do something else, compiling directly to the final binaries or collectors that go directly to the final binary, and not to the object. Of course, historically this was not always the case. Until you get into these corner cases, I assume that you will have the above experience when you get into the tools.

+4
source

It depends on the operating system and the compiler.

For example, in Amiga, if I remember correctly, absolute addresses were stored inside the executable on disk. But when the OS downloaded the binary, it would rewrite the addresses on the fly to fit into the memory area that it allocated for the program.

In your case, I think the addresses can be absolute in the 64k DOS limit of the "small" memory model. 64k is a segment in the 8086 architecture, and DOS allocates a full segment for each β€œsmall” memory model that it loads. The ".COM" files are uploaded, as in the 64K DOS segment.

I can’t specify the exact terminology and details, but the main thing is that it depends on the operating system and the compiler.

+3
source

Source: https://habr.com/ru/post/1205011/


All Articles