内存地址,指针,变量,值 - 幕后发生的事情

时间:2013-06-21 06:42:34

标签: variables pointers memory-address

这将是一个非常复杂的问题,但自从我开始学习指针以来,我一直非常好奇程序运行时幕后发生的事情。

据我所知,计算机内存通常被认为是一段长长的内存,均匀地划分为单个字节。当然,如下的图片唤起了这样一个比喻:

p_to_c pa alloc

有一件事我一直想知道,内存地址本身代表什么?我确定内存地址显示为8位十六进制值(例如/ 00EB5748)并非巧合。这是为什么?

此外,当我声明变量x时,内存级别会发生什么?编译器是否只是为数据存储保留一个随机地址(对于变量类型需要多少连续地址)?

现在假设x是一个无符号整数,占用2个字节的内存(即值范围从0到65536)。当我宣布x = 12时,发生了什么?是什么让我等于12?当我绘制概念图时,我通常有一个地址框(比如说& x)指向一个似乎什么都没有的变量(x),我确信这不能完全准确地描述正在发生的事情。

在二进制级别发生了什么?地址00EB5748是否被视为111010110101011101001000并在某处或1100处存储值为12?

主要是我的困惑&好奇心源于内存地址与声明的实际值之间的关系(例如/ 12,'a', - 355.2)。另一个例子,假设我们的地址00EB5748指向一个字符'',根据ASCII图表,它的值为115。地址是否通过在内存中翻转该位置的相应1和0来描述将值115存储为1字节的位置?

2 个答案:

答案 0 :(得分:1)

  1. 内存地址只是内存中给定字节的位置。第零个字节位于0x00000000。十分之一在0x0000000A。第65535位为0x0000FFFF。等等。
  2. 本地变量位于stack *上。在编译代码块时,编译器会计算保存所有局部变量所需的字节数,然后递增堆栈指针,以便所有变量都可以放在它下面(以及其他一些东西,如帧指针和返回地址,以及诸如此类的东西)。然后它只记得,例如,局部变量x与堆栈指针的偏移量为-2,foo位于偏移量-4,依此类推,并在下面的代码中引用这些变量时使用这些地址。
  3. 由于编译器知道x在地址(堆栈指针-2),因此当你执行x = 12时,这就是设置为值12的位置。
  4. 不完全确定我是否理解这个问题,但是你想要读取地址0x00EB5748的内存。 CPU中的控制单元读取指令,发现它是一个加载指令,并将地址(当然是二进制)传递给加载/存储单元,以及一些其他垃圾,例如要读取的字节数。然后LSU将该地址发送到某个内存(可能是L1缓存),并在一段时间后返回值12。然后,这些数据可用于放入寄存器,或发送给ALU进行算术运算等等。
  5. 这似乎是准确的,是的。回到第一个问题,地址只是“内存中的字节数0xWHATEVER”。
  6. 希望这至少澄清了一些事情。

    *我也应该解释堆栈。堆栈是为局部变量(以及其他一些东西)保留的内存的一部分。它从内存中的固定位置开始,并停在包含在称为堆栈指针的特殊寄存器中的内存地址处。首先,堆栈为空,因此堆栈指针只包含堆栈的开头。当您在堆栈上放置更多数据时,SP会递增。这意味着您可以随时将更多数据放在SP上的地址,然后递增SP,以便再次通过该地址的任何内容都是空闲内存。

答案 1 :(得分:1)

打开任何书。你会看到页面。每个页面都有一个数字。连续页面按连续编号编号。你有编号页面的混淆吗?我想不是。那你就不应该混淆计算机内存。 书籍是计算机时代之前的主要记忆存储设备。计算机存储器从书籍中得出基本概念:书籍有页面 - >计算机存储器有存储单元,书有页码 - >计算机内存有内存地址。

  • 有一件事我一直想知道,内存地址本身代表什么?

号。每个存储单元都有数字,就像书中的每一页一样。

  • 此外,当我声明变量x时,内存级别会发生什么?编译器是否只是为数据存储保留一个随机地址(对于变量类型需要多少连续地址)?

内存管理器标记一些占用的内存单元,并将第一个保留单元的地址告知编译器。编译器将变量的名称和类型与此地址相关联。 (这张照片来自我的头,可能不准确。)

  • 当我宣布x = 12时,发生了什么事?

当您声明变量x时,会为此变量保留内存单元格。现在你将12写入这些存储单元。请注意,12以某种方式进行二进制编码,具体取决于变量x的类型。如果x是unsigned int,它占用2个内存单元格,那么一个单元格将包含0,其他将包含12.因为12的二进制整数表示是

0000 0000 0000 1100
|_______| |_______|
  cell      cell  

如果12是浮点数,它将以其他方式编码。