In C, let’s say you have a variable called variable_name. Let’s say it’s located at 0xaaaaaaaa, and at that memory address, you have the integer 123. So in other words, variable_name contains 123.
I’m looking for clarification around the phrasing “variable_name is located at 0xaaaaaaaa“. How does the compiler recognize that the string “variable_name” is associated with that particular memory address? Is the string “variable_name” stored somewhere in memory? Does the compiler just substitute variable_name for 0xaaaaaaaa whenever it sees it, and if so, wouldn’t it have to use memory in order to make that substitution?
Variable names don’t exist anymore after the compiler runs (barring special cases like exported globals in shared libraries or debug symbols). The entire act of compilation is intended to take those symbolic names and algorithms represented by your source code and turn them into native machine instructions. So yes, if you have a global
variable_name, and compiler and linker decide to put it at0xaaaaaaaa, then wherever it is used in the code, it will just be accessed via that address.So to answer your literal questions:
The toolchain (compiler & linker) work together to assign a memory location for the variable. It’s the compiler’s job to keep track of all the references, and linker puts in the right addresses later.
Only while the compiler is running.
Yes, that’s pretty much what happens, except it’s a two-stage job with the linker. And yes, it uses memory, but it’s the compiler’s memory, not anything at runtime for your program.
An example might help you understand. Let’s try out this program:
Pretty straightforward, right? OK. Let’s take this program, and compile it and look at the disassembly:
See that
movlline? It’s grabbing the global variable (in an instruction-pointer relative way, in this case). No more mention ofx.Now let’s make it a bit more complicated and add a local variable:
The disassembly for this program is:
Now there are two
movlinstructions and anaddlinstruction. You can see that the firstmovlis initializingy, which it’s decided will be on the stack (base pointer – 4). Then the nextmovlgets the globalxinto a registereax, and theaddladdsyto that value. But as you can see, the literalxandystrings don’t exist anymore. They were conveniences for you, the programmer, but the computer certainly doesn’t care about them at execution time.