【问题标题】:Stack data size堆栈数据大小
【发布时间】:2018-01-29 14:01:54
【问题描述】:

我找不到这个问题的答案。入栈的数据大小是多少?

假设您将一些数据压入堆栈。例如一个int。然后堆栈指针的值减少4个字节。

直到今天我都认为可以压入堆栈的最大数据不能大于指针大小。但是我做了一个小实验。我用 C# 写了一个简单的应用程序:

int i = 0;    //0x68 <-- address of variable
int j = 1;    //0x64 
ulong k = 2;  //0x5C
int l = 3;    //0x58

根据我的预测,ulong 应该分配在堆上,因为它需要 8 个字节,而我在 32 位系统上工作(因此指针大小为 4 个字节)。那会很奇怪,因为这是一个简单的局部变量。

但它被压入堆栈。

所以我认为我对堆栈的看法有问题。因为堆栈指针如何“知道”他是否必须更改 4 个字节(如果我们推送 int)或 8 个字节(如果我们推送 long 或 double)或仅 1 个字节?

或者局部变量的值可能在堆上,但这些变量的地址在堆栈上。但这没有任何意义,因为这就是对象的处理方式。当我创建对象(使用 new 关键字)时,对象是在堆上分配的,并且该对象的地址被推送到堆栈上,对吧?

那么有人可以告诉我(或提供文章链接)它是如何工作的吗?

【问题讨论】:

标签: stack size


【解决方案1】:

编译器或运行时环境知道您正在处理的数据类型,并且知道如何构造成适合堆栈的单元。因此,例如,在堆栈指针仅在 32 位块中移动的架构上,编译器或运行时将知道如何将比 32 位更长的数据元素格式化为多个 32 位块来推送它们.类似地,它将知道如何将它们从堆栈中弹出并重建适当类型的变量。

这里的问题对于堆栈而言与对于任何其他类型的内存并没有真正的不同。 CPU 架构将被优化以处理特定大小的少量数据元素,但编程语言通常提供更广泛的数据类型。编译器或运行时环境必须处理这种情况所需的数据打包和解包。

【讨论】:

  • 所以我想对了。堆栈数据大小只是指针大小,知道如何处理较大数据的是编译器或运行时环境。因此,例如,如果堆栈指针仅移动 4 个字节(假设您不能将堆栈指针更改超过 4 个字节 - 我知道这不是真的),所以从堆栈中弹出 long 值需要 2 个堆栈指针移动和魔术编译器技巧来创建来自两个 4 字节值的 8 字节值。对吗?
  • 这对我来说听起来很正确。然而,在实践中,不同的 CPU 架构对如何在堆栈(以及其他任何地方)对齐或填充数据有不同的看法,因此编译器需要考虑这些因素。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-10
  • 2010-11-24
  • 2021-03-26
  • 2011-11-24
  • 2017-07-14
  • 2017-06-26
  • 2015-11-22
相关资源
最近更新 更多