本文介绍了每个 PUSH 指令是否在 x64 上推送 8 字节的倍数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 x64 上,每个 PUSH 指令是否推送 8 字节的倍数?如果没有,它会推动多少?

On x64, does each PUSH instruction push a multiple of 8 bytes? If not, how much does it push?

另外,每个函数参数消耗多少堆栈空间?

Also, how much stack space does each function parameter consume?

推荐答案

没有,但在实践中,总是将一个 8 字节的值压入堆栈.

No, but in practice, one always pushes an 8 byte value onto the stack.

函数参数消耗不同数量的堆栈空间,具体取决于函数参数的大小以及它是在堆栈中、寄存器中还是通过引用传递.

Function parameters consuming varying amounts of stack space depending on the size of the function parameter and whether it is passed in the stack, in the registers, or passed by reference.

如果通过压入在堆栈中传递函数参数,那么有方便的压入8字节的压入指令这一事实强烈建议您将参数作为一个 8 字节的值.对于指针、int64 和普通双精度,这显然很容易.对于 char、bool、short 和其他内存较小的类型,大多数编译器所做的是将值推送到 8 字节块中.占用 16 或 32 个字节的类型可能由编译器通过多个推送指令推送.较大的值往往不会通过推送而被传递;通常编译器会尝试传递指向更大值的指针,而不是传递值本身.{我已经构建了一个可以传递任意大值的编译器,但它通过在堆栈中腾出空间,然后执行块移动指令来实现].详细信息因编译器而异,并取决于正在编译的程序的语言语义.

If one passes a function parameter in the stack by pushing, then the fact that there are convenient push instructions that pushes 8 bytes strongly suggests that you pass the parameter as an 8 byte value. For pointers, int64 and plain doubles, this is obviously easy. For char, bool, short, and other types whose memory size is smaller, what most compilers do is push the value in an 8 byte chunk. Types that take 16 or 32 bytes might be pushed by the compiler with several push instructions. Bigger values tend not to get passed by pushing; often a compiler tries to pass a pointer to a bigger value rather than pass the value itself. {I've built a compiler that can pass arbitrarily big values, but it does so by making space in the stack, and then executing a block move instruction]. Details vary from compiler to compiler, and according to the language semantics of the program being compiled.

一个真正聪明的编译器可能会注意到几个参数很小并且可以打包成一个 8 字节的数量,只需要一次推送.我还没有看到有人真的这样做,可能是因为将这些值打包到一个寄存器中需要一些工作,而且推送指令在设计和缓存方面已经非常快了.

A really clever compiler might notice that several arguments are small and can be packed into an 8 byte quantity that only requires a single push. I've not seen one actually do that, probably because it takes work to pack such values together into a register, and push instructions are already pretty fast by design and by cache.

可以将较小的值压入堆栈.根据架构,这是合法的,但如果推送的小值集不是 8 字节的倍数,则可能会导致未对齐的访问性能下降.然后必须小心地正确弹出非倍数以恢复堆栈对齐.在我的经验中没有用(请参阅 Peter Cordes 的代码高尔夫评论).

It is possible to push smaller values onto the stack. This is legal according to the architecture, but is likely to cause a mis-aligned access performance hit if the set of small values pushed isn't a multiple of 8 bytes. And then one must be careful to pop off the non-multiple correctly to restore stack alignment. Not useful in my experience (see code golf comment by Peter Cordes).

如果您将值传递到寄存器中,则不会推送任何内容:-}

If you pass the value in a register, nothing gets pushed :-}

人们可能会安排将参数值存储在堆栈中众所周知的位置.然后没有任何推送:-}

One might arrange to store parameter values in a well known locations in the stack. Then there isn't any push :-}

这篇关于每个 PUSH 指令是否在 x64 上推送 8 字节的倍数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-29 08:24