0
$\begingroup$

Suppose I write a program as below:

int main()
{
int a = 3;
int b = 4;  
return 0;
}

Suppose the computer stores the address of 'a' as 0x00104. How does it associate 'a' with 0x00104?

$\endgroup$
  • $\begingroup$ My OS knowledge is already pretty rusty and needs some re-polishing. However, if I remember correctly, there are three ways of mapping a to some memory address and I think it is also being handled by the compiler. One way that I do remember is that the compiler directly associates a memory address like0x00104 with a. The other two? I've forgotten. I'll drop an answer once I get to review my OS concepts. $\endgroup$ – Sean Francis N. Ballais Dec 2 '18 at 14:29
  • $\begingroup$ Additionally, I recommend reading an OS book as it should cover your question. What we used in university is Operating System Concepts by Silberschatz, Galvin, and Gagne. I highly recommend the book. $\endgroup$ – Sean Francis N. Ballais Dec 2 '18 at 14:31
2
$\begingroup$

Suppose the computer stores the address of 'a' as 0x00104.

No, 'computer'(?) nowhere stores the address of 'a'. Compiler or assembler converts source code into object modules. Those object modules have instructions and data. 'a' is symbolic address which is bound by compiler to relocatable address. The linkage editor or loader in turn bind the relocatable address to absolute address. So, there is no storage but binding. Note that the absolute binding can be done at either compile time, load time or execution time where relocatable address binding will be done in any case by the compiler.

$\endgroup$
0
$\begingroup$

"a" may never make it into memory the way you are thinking.

At compile time what you know as "a" will cease to exist.

The line "int a = 3" will be replaced with an assembly instruction likely to look something like this:

LOAD R1 3

R1 is a register inside the CPU (could be R2, R3, etc). This assembly instruction tells the CPU to put the value 3 in R1. The compiler generates a list of assembly instructions which comprises your program executable. When you execute that program "LOAD R1 3" will appear somewhere in your computer memory, waiting to be loaded into your CPU instruction register (A register which tells the CPU what to do next, different from the R1 register). Its difficult to say what memory address that will end up in -- however i suspect that you are referring to the address of the variable in the same sense that you would get if you created a pointer to that variable.

As written in your program the value of "a" will never make it into any memory address. The compiler could write "a" to memory but would have no need to do so here.

There are two ways for the value of "a" to make it to memory in your program. One is by loading it onto the stack:

int main() { 
int a = 3; 
int b = 4; 
someFunctionCall();
b = a + 1;
return 0;
}

If the compiler is simple it will issue an assembly instruction like this:

SW SP R1

This means store word (SW) at the memory address of the stack pointer (SP, another CPU register which stores a special memory address) and the value to store is in R1. The address R1 gets loaded in will vary and changes each time something new gets stored.

The second way for "a" to make it into memory would be on the heap. If you did something like:

int main() { 
int [] a;
a = new(1);
A[0] = 3;
int b = 4; 
return 0; 
}

Not 100% sure on the syntax here -- my C is rusty. The heap is controlled by the operating system and therefore new() can be complicated. The OS will return a memory address, R1 will be loaded with a 3, then sent to memory using a similar instruction as the SW above. The address that the OS returns can be quite random.

$\endgroup$
  • $\begingroup$ Are you sure the value of a will land in a register? gcc does movl $3, -8(%rbp) on x64, which means it lands on the stack. Only with register int a do I get movl $3, %ebx (after adding some operation with a; otherwise it is optimized away). $\endgroup$ – dkaeae Feb 1 at 8:26
  • $\begingroup$ GCC is a smart compiler. It probably optimized your code somehow. Set a to a constant then have b read in from either input or as a parameter to your program. Then add a and b and print it. It'll land in a register, I promise. $\endgroup$ – a1s2d3f4 Feb 1 at 13:52
  • $\begingroup$ Nope. I ran it with -O0 and the output is the same. $\endgroup$ – dkaeae Feb 1 at 13:54
  • $\begingroup$ Also, regarding your suggestion: GCC then still does movl $3, -4(%rbp); next it does movl -4(%rbp), %edx and operates on edx and eax, but this does not change the fact a first lands on the stack. $\endgroup$ – dkaeae Feb 1 at 14:07
  • $\begingroup$ Lets assume the operation is c = a + b; There are two possibilities. Either GCC recognizes it can precompute a + b and does so or it puts the value in a register. I don't really no why it would put it on the stack. $\endgroup$ – a1s2d3f4 Feb 1 at 14:10
0
$\begingroup$

The compiler analyses your program, and lays out space for whatever variables it really needs in memory. If the compiler is smart, here it will see that neither anor b are ever used, and just don't assign space to them. For another program, the compiler may notice that a is always some fixed value, and use that one throughout, again not giving a an address. Yet another program uses a and b alternatively, the compiler is then allowed to place them at the same address. Or the value of a is short-lived, it is computed into a register, used and discarded. No address assigned. If you only ever use e.g. 5 * a + 3, the compiler could invent it's own variable to hold that value and never even store a's value.

The compiler's job is to write an assembly program that behaves as if it is doing as you wrote, but hopefully more efficient. As a programmer, you can't "see" where the compiler places your variables (if at all), it is free to juggle with them if worthwhile.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.