简体   繁体   中英

The relation of Stack, Memory Heap and assembly code

I'm trying to understand the compilation process of a C/C++ code and it's memory management in more details. Assuming the following code:

#include <iostream>

int main() {
    int a = 5;
    int *b = (int *) malloc(40);
    return 0;
}

I know a and b will be created on the stack and value of b (memory that it points to) will be on the heap.

The code compiled to assembly will look like this:

    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register %rbp
    subq    $16, %rsp
    movl    $40, %eax
    movl    %eax, %edi
    movl    $0, -4(%rbp)
    movl    $5, -8(%rbp)
    callq   _malloc
    xorl    %ecx, %ecx
    movq    %rax, -16(%rbp)
    movl    %ecx, %eax
    addq    $16, %rsp
    popq    %rbp
    retq

My Question is;

What does a is on the stack (memory) mean here? according the above assembly, a is embedded directly into the instruction $5, -8(%rbp) , there is no reference to a memory location. If it IS on the memory then what's the address of a ?

I know _malloc creates 40 bytes on the heap (memory) and returns the first memory address but I cannot see how the stack gets populated, there is no interaction with the memory here other than the instructions themselves being fetched form it.

What does a is on the stack (memory) mean here?

It means that the object named by the variable is stored on the memory section called the stack, AKA the call stack. The call stack contains local automatic variables of functions.

 movl $5, -8(%rbp)

rbp is the frame pointer. It points to the current frame of the call stack . This instruction moves the constant 5 to the memory pointed by rbp with offset of -8 bytes. In other words, this instruction initialises the variable a , which is on the stack.

If it IS on the memory then what's the address of a?

The address of a appears to be rbp - 8 where rbp is the address stored in the frame pointer. In the realm of C++, you can use the addressof operator to get the address.


None of stack (in relation to memory), heap , frame , rbp etc. are defined by the C++ language. These words have meaning in context of the particular CPU architecture.

There's nothing in the language which says a will be on the stack. The compiler is entitled to put it wherever it wants; and in particular, if it does not need to put it anywhere, it doesn't have to.

The variable a is never used after you put 5 into it, so a decent optimizer would throw that line away entirely.

However, in your particular case, it looks to me like a really is on the stack. It's at -8 bytes off the frame pointer in %rbp. Which is to say, the address of a is -8(%rbp), or "the value in register rbp, minus 8", which is pretty near the top of the stack.

To get more detailed. The stack exists in memory. Let's assume stacks grow downwards in memory (this is conventional) so that the "top" of the stack grows towards smaller addresses. There is a "stack pointer" that points to the top of the stack, ie, the address of the last thing added to the stack (I'm speaking in generalities here).

To allocate N bytes of stack space, all that is necessary is to subtract N from the stack pointer. The generated code usually does this in one instruction, since it knows the total space needed for the function being entered. To deallocate that space, the code can either (a) add N, or (b) restore the pre-subtraction value of the stack pointer, which it had saved somewhere. The choice is really defined finer details of how the compiler system wants to manage the stack.

There are auxiliary registers that might be employed in stack management. A common one is to have a "frame pointer", which is the role that %rbp is filling here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM