Reputation: 2717
I am trying to learn operating systems. At present i am in virtual addressing. What book says that if we have one static variable
and one local variable
and we update them and sleep for some time and try to print their addresses then across multiple such processes running one will get same memory address.
This is because each process feel like it has whole memory and has no control of physical memory so address will remain same among various process running at the same time. I understand this but when i run my program i am getting same address across static variables but different across local variables. With my little operating systems knowledge i am not able to understand why this is happening. This is my code
int staticvar = 0;
int main(int argc, char const *argv[])
{
int localvar = 0;
staticvar += 1;
localvar += 1;
sleep(10);
printf("static address: %x, value: %d\n", &staticvar, staticvar );
printf("static address: %x, value: %d\n", &localvar, localvar );
return 0;
}
This is my output when i run three different processes simultaneously.
./a.out
static address: 60104c, value: 1
static address: 67c6128c, value: 1
./a.out
static address: 60104c, value: 1
static address: 89e2c11c, value: 1
./a.out
static address: 60104c, value: 1
static address: 226e03dc, value: 1
Upvotes: 2
Views: 2100
Reputation: 12610
Local variables are allocated on the stack frame of the function called. The stack frame is referenced through the stack pointer (SP) register which is initialized by the OS upon start of the process. The program uses the SP to dynamically allocate stack space and look up the values stored there. So this type of access is prepared to use a dynamic address, and knowing that, the OS can choose to initialize the process' stack frame wherever it sees fit best in the current context.
"Static" variables, on the other hand, are usually referenced by constant addresses from the compiled (assembler) code. That's why they must reside at a known-at-compile-time location.
Edit:
As someone noted, the value of the SP changes through program execution, depending on stack usage. Therefore, if you call the same funtion from different parts of the program, the address of the local variable may even be different each time.
Upvotes: 3
Reputation: 1615
First, int staticvar = 0;
defined by you is called global variable
not really a static variable. To define static variable you must add static
keyword while declaring the variable, e.g. static int staticvar
Now, if you see the assembly code of your C
file, you'll notice that staticvar
has been referenced at compile time itself. That is the reason, you're seeing the same memory location for staticvar
all the time. Same goes true for, if you have global/static variable defined also.
However, the local variable gets the memory reserved at run time in stack
, which OS kernel will have control. That is why you're seeing different memory location at every run.
And this behaviour holds good even if you don't put sleep()
in your code.
.file "test11.c"
.local staticvar
.comm staticvar,4,4
.section .rodata
.align 8
.LC0:
.string "static address: %x, value: %d\n"
.LC1:
.string "local address: %x, value: %d\n"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $32, %rsp
movl %edi, -20(%rbp)
movq %rsi, -32(%rbp)
movl $0, -4(%rbp)
movl staticvar(%rip), %eax
addl $1, %eax
movl %eax, staticvar(%rip)
movl -4(%rbp), %eax
addl $1, %eax
movl %eax, -4(%rbp)
movl $3, %edi
movl $0, %eax
call sleep
movl staticvar(%rip), %edx
movl $.LC0, %eax
movl $staticvar, %esi
movq %rax, %rdi
movl $0, %eax
call printf
movl -4(%rbp), %edx
movl $.LC1, %eax
leaq -4(%rbp), %rcx
movq %rcx, %rsi
movq %rax, %rdi
movl $0, %eax
call printf
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (GNU) 4.4.7 20120313 (Red Hat 4.4.7-11)"
.section .note.GNU-stack,"",@progbits
Upvotes: 1