【问题标题】:x86 Can push/pop be less than 4 bytes? [duplicate]x86 push/pop 可以小于 4 字节吗? [复制]
【发布时间】:2013-03-29 02:43:35
【问题描述】:

您好,我正在阅读弗吉尼亚大学的 x86 指南,其中指出,推送和弹出堆栈要么删除堆栈,要么将 4 字节数据元素添加到堆栈中。

为什么设置为 4 个字节?这可以改变吗,你能通过推送更小的数据元素来节省堆栈上的内存吗?

如果有人想查看该指南,可以在这里找到: http://www.cs.virginia.edu/~evans/cs216/guides/x86.html

【问题讨论】:

  • 该语句仅适用于 32 位模式,您还可以推送/弹出 2 字节元素。

标签: memory assembly x86 stack


【解决方案1】:

简短回答:是的,16 位或 32 位。而且,对于x86-64,64 位。

堆栈的主要原因是从嵌套函数调用返回并保存/恢复寄存器值。它也通常用于传递参数和返回函数结果。除了最小的参数外,这些项在处理器设计上通常具有相同的大小,即指令指针寄存器的大小。对于 8088/8086,它是 16 位。对于 80386 和后续版本,它是 32 位的。因此,在其他大小上操作的堆栈指令几乎没有价值。

还有内存总线上数据大小的考虑。检索或存储一个字所花费的时间与处理一个字节所花费的时间相同。 (除了 8088,它有 16 位寄存器,但有 8 位数据总线。)对齐也起作用。堆栈应在字边界上对齐,以便每个值都可以作为一个内存操作检索。权衡通常是为了节省时间而不是节省内存。要将一个字节作为参数传递,通常使用一个字。 (或者,根据编译器可用的优化,将使用一个字大小的寄存器,完全避免堆栈。)

【讨论】:

  • 在 x86-64 中,您不能推送存储在内存中的 32 位寄存器或值,​​只能推送存储在内存中的 16 位或 64 位寄存器和值。 push axpush raxpush word [rax]push qword [rax] 都是有效的 x86-64 指令,但 push eaxpush dword [rax] 在 x86-64 中无效。
  • 历史记录,(很少使用的)80188(16位字,8位数据总线)和(一度流行)386SX(32位字,16位数据总线) ) 在数据总线大小不匹配方面与 8088 处于同一条船上。
  • 对于“堆栈应该在字边界上对齐,以便每个值都可以作为一个内存操作检索。”,这适用于函数内部的局部变量吗?
  • @汤姆森。是的,编译器确实在堆栈和寄存器中安排局部变量,以便优化访问时间。通常不需要局部变量以任何顺序或没有填充的方式在堆栈上布局。
猜你喜欢
  • 1970-01-01
  • 2019-10-30
  • 1970-01-01
  • 2020-03-27
  • 2013-04-05
  • 2016-06-21
  • 1970-01-01
  • 2011-05-31
  • 1970-01-01
相关资源
最近更新 更多