如何为变量分配内存地址?

时间:2019-03-02 20:09:45

标签: operating-system

如果我写一条指令x = 7,我将x理解为某个地址。然后,什么为x分配一个内存地址?这个地址是虚拟地址,然后转换为物理内存地址吗?

2 个答案:

答案 0 :(得分:0)

  

如果我写一条指令x = 7,我将x理解为某个地址。然后,什么为x分配一个内存地址?

这取决于var x的类型。

  1. 如果x全局或静态变量,则有几种工具将配合使用以为其指定地址

    • 编译器将在目标文件中写入存储4个字节的名为x的全局变量所需的文件。
    • 链接器将收集对象文件中的所有全局变量,将它们放在数据段中,然后为它们选择一个位置。例如,x将位于@data_segment+0x1000。然后,链接器将通过x
    • 修改代码中对@data_segment+0x1000的所有引用。
    • 在运行程序时,加载程序将首先要求操作系统内存存储不同的段,包括数据段。然后,人们就会知道@data_segment的值和x 1 的实际地址。
  2. 如果x是局部变量,则情况会稍微简单一些。所有局部变量都在堆栈中,并且其地址是由编译器相对于堆栈(或帧)指针计算的。因此x的地址将类似于@stack_pointer+8,它是由编译器生成的。但是它的实际值只有在执行时才知道,并且取决于堆栈指针。

  3. 如果x是动态分配的(malloc-ed),则仅在运行时知道其地址。 malloc()向操作系统请求内存块,并在其中动态定位vars。 x的位置将取决于malloc()

  4. 管理的内存中的可用空间
  

此地址是虚拟地址,然后转换为物理内存地址吗?

计算机看到的所有地址都是虚拟地址,它们会转换为物理内存地址。


1 程序段(包括数据段)的虚拟地址过去对于程序的不同执行是恒定的,但现在不再适用。出于安全原因,它们是randomized

答案 1 :(得分:0)

通常有四种方法可以完成此操作。

1)变量被映射到硬件寄存器。在这种情况下,x没有地址。

2)变量具有绝对地址。通常认为这是错误的形式,因为使用绝对地址的代码无法重定位。意味着必须将其放置在地址空间中的固定位置。但是,在某些情况下,变量必须位于特定的位置,例如设备的某些接口。

在这种情况下,x的地址可以由编译器或链接器指定。

3)将该变量定义为与堆栈相关的寄存器的偏移量。是大多数编程语言中用于实现局部变量的方法。如果您有4个字节的整数,并说一个C声明,如

int x,y;

在没有其他变量的函数中,该函数的顶部有类似以下内容的指令:

SUBL2 #8, SP ; Allocate 8 bytes from the stack
MOVL  SP, BP ; Set the Base Pointer Register to the start of the allocation

其中SP是堆栈指针,而BP是一些基于指针的寄存器。

在这种情况下,x可能是位于BP + 0处的偏移量,y可能是在BP + 4处的偏移量。

因此类似

x = y 

看起来像

MOVL X(BP),Y(BP)

或写为:

MOVL(BP),4(BP)

x和y的存储位置在运行时完全确定。只有相对于基本指针寄存器的偏移量是已知的。实际上,如果递归地或通过中断调用包含它们的函数,则可能同时存在多个具有不同地址的x和y。

4)存储器位置是另一个寄存器偏移量(通常是程序计数器)。

假设您使用的是传统的大写FORTRAN,其中所有变量都是静态的。编译器通常会确定变量的位置,但使用程序计数器寄存器(或某些其他寄存器)的偏移量来引用它。变量在运行时保留在固定位置,但是位置可以是可变的。使用这样的偏移量可使代码独立于位置。表示可以将其加载到内存中的任何位置。这样一来,代码便可以在可以由多个程序使用的共享库中使用。

通常,编译器会为变量设置一些位置,然后由链接程序修复。