2

Consider the following C++ function:

void doStuff() {
    Thing thingA;
    Thing thingB;
    thingA.doSomething();
    // .. etc
}

During the execution of this function, variables thingA and thingB are allocated on the stack. That means that the variable thingA represents some address on the stack, and it's value is what's allocated in this address (correct me if I'm wrong).

What I don't understand is this: when we call thingA.doSomething(), how does the CPU know what the address represented by thingA is? The value held by thingA is currently buried in the stack under some other data. How does the CPU know what the address that leads to this value is, in order to reach this data?

3
  • 3
    The CPU knows because the C++ compiler produces assembly code that tells the CPU exactly where in the stack thingA is and where the functions are for a Thing. I've never worked much with C++ (although I've done embedded assembly work), so I don't know all the details. Just remember that modern CPUs are incredibly complex, but at their essence, they're dumb machines. They do exactly what you tell them to do, nothing more.
    – mgw854
    Commented Oct 10, 2014 at 2:03
  • 2
    Please give understanding the stack a read. It is based on MIPS, which is a very common architecture used for educational programming. A simulator for it (SPIM) can be found at spimsimulator.sourceforge.net
    – user40980
    Commented Oct 10, 2014 at 2:03
  • and I'll point out that that is for MIPS... different systems will do different things with different conventions for different architectures. You've got issues like preserving certain registers (or none, or all) when switching stack frames (the usage conventions can be quite complex). This isn't a simple question and easily the subject of several lectures in machine architecture or compiler design. Note that sometimes, things will never be on the stack (in a $t register), or may be in a $s register and the next function saves it.
    – user40980
    Commented Oct 10, 2014 at 2:18

2 Answers 2

5

The compiler will choose a different offset from the stack pointer for each stack-allocated variable. For example, stackPointer + 0 bytes might point to thingA, and stackPointer + 8 bytes might point to thingB.

The compiler will make sure that the offsets are large enough that the memory used for each variable doesn't overlap. On each function call, the stack pointer is moved to make space for the callee's variables. On function return, the stack pointer is reset back to where it was in the caller, so that variable references in the caller still work correctly.

2
  • I can't see how this answers the question about how member functions are found.
    – tofro
    Commented Sep 11, 2016 at 13:26
  • @tofro You might read the question again; the OP never asks how member functions are found.
    – Alex D
    Commented Sep 11, 2016 at 20:05
4

The first thing to note is that to the CPU, the stack is just a portion of the total memory that gets used in a particular way. Addresses of objects on the stack are indistinguishable from addresses of other objects (globals and heap allocated objects).

When invoking a method or a function, the compiler knows where the object and parameters are located and tells the compiler where to look for them. This can be a memory address or a CPU register.

Due to the way that the stack is typically used, objects on the stack usually don't have a fixed address. But they do have a fixed address relative to the other stack-allocated objects in the same function and that knowledge is used to determine where they are exactly located.
In most CPU architectures, two registers are used to keep track of the top of the stack and the location relative to which the stack-allocated objects in the current function invocation are located. These registers are sometimes referred to as respectively the stack pointer and the base pointer.

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