简体   繁体   English

静态变量的地址相同,但局部变量的地址不同

[英]Same address for static variable but different for local variable

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. 哪本书说过,如果我们有一个static variable和一个local variable ,并且更新它们并休眠一段时间,然后尝试打印它们的地址,那么在多个运行一个的此类进程中,将获得相同的内存地址。

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

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. 堆栈帧通过堆栈指针(SP)寄存器引用,该寄存器由OS在进程开始时初始化。 The program uses the SP to dynamically allocate stack space and look up the values stored there. 该程序使用SP来动态分配堆栈空间并查找存储在其中的值。 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. 正如有人指出的那样,SP的值根据程序的使用情况在程序执行过程中发生变化。 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. 因此,如果从程序的不同部分调用相同的功能,则局部变量的地址甚至可能每次都不同。

First, int staticvar = 0; 首先, int staticvar = 0; defined by you is called global variable not really a static variable. 您定义的称为global variable实际上不是静态变量。 To define static variable you must add static keyword while declaring the variable, eg static int staticvar 要定义静态变量,必须在声明变量的同时添加static关键字,例如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. 现在,如果看到C文件的汇编代码,您会注意到staticvar在编译时已被引用。 That is the reason, you're seeing the same memory location for staticvar all the time. 这就是原因,您一直都在为staticvar查看相同的内存位置。 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. 但是,局部变量在运行时在stack保留了内存,该内存由OS内核控制。 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. 即使您没有在代码中放置sleep() ,这种行为也会保持良好的sleep()

        .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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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