const variables in local and global scope in assembly

Viewed 580

I've compiled the following C code in Compiler Exporer to see how it handles the const keyword:

int a=1;
const b=2;
int func () {
    int c=3;
    const int d=4;
}

        .section        .data
a:
        .long   1
        .section        .rodata
b:
        .long   2
func:
        pushq   %rbp
        movq    %rsp, %rbp
        movl    $3, -4(%rbp)
        movl    $4, -8(%rbp)
        nop     # also, why does it add a nop here?
        popq    %rbp
        ret

From what I can tell, for a variable defined outside a function (global to the file), it adds a label at the top. However, if it is a const variable, then the variable at the top is placed in the read-only section. My question then is for the following local variable:

const int d=4;

How is its 'constant-ness' managed, as it's just a value on the stack, and can't any value on the stack be freely modified? Or, in assembly, is there no such thing as a constant local-variable, and this is just a compiler-enforced concept?

2 Answers

Just try it.

int fun ( void )
{
    const int d=4;
    return(d);
}

00000000 <fun>:
   0:   e3a00004    mov r0, #4
   4:   e12fff1e    bx  lr



int fun ( void )
{
    const int d=4;
    return(d);
}
int fun1( void )
{
    int d=4;
    d=5;
    return(d);
}
int fun2 ( void )
{
    const int d=4;
    d=5;
    return(d);
}

so.c: In function ‘fun2’:
so.c:16:6: error: assignment of read-only variable ‘d’


int fun ( void )
{
    const int d=4;
    return(d);
}
int fun1( void )
{
    int d=4;
    d=5;
    return(d);
}

00000000 <fun>:
   0:   e3a00004    mov r0, #4
   4:   e12fff1e    bx  lr

00000008 <fun1>:
   8:   e3a00005    mov r0, #5
   c:   e12fff1e    bx  lr

Global variables are global, get a memory assignment in some segment, locals are locals, unless declared static (local globals) they live on the stack or in registers. Const just indicates to the compiler it can generate code based on the assumption that variable is read only not read/write. A better compiler will complain if you try to write to a read only declared variable. So the difference between const int and int is read/only vs read/write.

If you don't take the address, you don't need to keep a const local in data memory anywhere. The asm equivalent is NASM d equ 4 or GAS d = 4 so you can just use it as an immediate when you do need it.

Same as a non-const int that happens not be modified: Yes, constness for locals is purely a compile-time thing that the compiler enforces to help you catch bugs.

Related