x86的push/pop指令是否可以少于4个字节?

8

你好,我正在阅读弗吉尼亚大学的x86指南,其中提到压入和弹出堆栈会将一个4字节的数据元素添加或移除到堆栈中。

为什么要设置为4个字节?这个大小可以改变吗?通过将较小的数据元素压入堆栈中,能够节省内存吗?

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


1
那个语句在32位模式下只有部分适用,而且您还可以推送/弹出2字节元素。 - harold
1个回答

11

简单回答:是的,可以使用16位或32位。对于x86-64,可以使用64位。

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

还考虑到内存总线上数据的大小。检索或存储一个字与一个字节需要相同的时间。(除了具有16位寄存器但8位数据总线的8088之外。)对齐也发挥作用。堆栈应该在字边界上对齐,以便每个值可以作为一个内存操作检索。折衷通常被认为是为了节省时间而不是节省内存。传递一个字节作为参数,通常使用一个字。 (或者,根据编译器可用的优化,可以使用一个字大小的寄存器,完全避免使用堆栈。)


14
еңЁx86-64жһ¶жһ„дёӯпјҢжӮЁж— жі•жҺЁйҖҒ32дҪҚеҜ„еӯҳеҷЁжҲ–еҶ…еӯҳдёӯеӯҳеӮЁзҡ„еҖјпјҢеҸӘиғҪжҺЁйҖҒ16дҪҚжҲ–64дҪҚеҜ„еӯҳеҷЁд»ҘеҸҠеҶ…еӯҳдёӯеӯҳеӮЁзҡ„еҖјгҖӮ push axпјҢpush raxпјҢpush word [rax]е’Ңpush qword [rax]йғҪжҳҜжңүж•Ҳзҡ„x86-64жҢҮд»ӨпјҢдҪҶжҳҜpush eaxе’Ңpush dword [rax]еңЁx86-64дёӯж— ж•ҲгҖӮ - nrz
历史注释:(极少使用的)80188(16位字,8位数据总线)和(曾经有一段时间相当流行的)386SX(32位字,16位数据总线)与8088一样存在数据总线大小不匹配的问题。 - Brian Knoblauch
“堆栈应该在字边界上对齐,以便每个值可以作为一个内存操作检索。”这适用于函数内的局部变量吗? - Thomson
1
@Thomson。是的,编译器确实会将局部变量排列在堆栈和寄存器中,以优化访问时间。通常没有要求局部变量按任何顺序或无填充地放置在堆栈上。 - Tom Blodget

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接