gpt4 book ai didi

assembly - 当我们有一个红色区域时,为什么我们需要堆栈分配?

转载 作者:行者123 更新时间:2023-12-04 13:26:16 25 4
gpt4 key购买 nike

我有以下疑问:

众所周知,System V x86-64 ABI在堆栈帧中为我们提供了一个固定大小的区域(128字节),即所谓的redzone。
因此,因此,我们不需要使用sub rsp, 12。只需创建mov [rsp-12], X即可。

但是我不明白这一点。为什么这有关系?是否有必要在没有redzone的情况下使用sub rsp, 12?毕竟,一开始堆栈的大小是有限的,所以sub rsp, 12为什么很重要?我知道这使我们有可能关注堆栈的顶部,但是那一刻让我们忽略它。

我知道一些指令使用rsp值(例如ret),但是在那一刻不关心它。

问题的症结在于:
我们没有Redzone,我们已经完成了:

function:
mov [rsp-16], rcx
mov [rsp-32], rcx
mov [rsp-128], rcx
mov [rsp-1024], rcx
ret

有区别吗?
function:
sub rsp, 1024
mov [rsp-16], rcx
mov [rsp-32], rcx
mov [rsp-128], rcx
mov [rsp-1024], rcx
add rsp, 1024
ret

最佳答案

“红色区域”不是严格必需的。用您的话来说,它可以被认为是“毫无意义的”。使用红色区域可以执行的所有操作,也可以按照IA-32 ABI的传统方式进行。
这是AMD64 ABI关于“红色区域”的内容:

The 128-byte area beyond the location pointed to by %rsp is considered to be reserved and shall not be modified by signal or interrupt handlers. Therefore, functions may use this area for temporary data that is not needed across function calls. In particular, leaf functions may use this area for their entire stack frame, rather than adjusting the stack pointer in the prologue and epilogue. This area is known as the red zone.


红色区域的真正目的是作为优化。它的存在使代码可以假定 rsp下的128个字节不会被信号或中断处理程序异步破坏,这使其有可能用作临时空间。这使得不必通过在 rsp中移动堆栈指针来在堆栈上显式创建暂存空间。这是一种优化,因为现在可以省去减少和还原 rsp的指令,从而节省了时间和空间。
所以是的,虽然您可以使用AMD64来做到这一点(并且需要使用IA-32来做到这一点):
function:
push rbp ; standard "prologue" to save the
mov rbp, rsp ; original value of rsp

sub rsp, 32 ; reserve scratch area on stack
mov QWORD PTR [rsp], rcx ; copy rcx into our scratch area
mov QWORD PTR [rsp+8], rdx ; copy rdx into our scratch area

; ...do something that clobbers rcx and rdx...

mov rcx, [rsp] ; retrieve original value of rcx from our scratch area
mov rdx, [rsp+8] ; retrieve original value of rdx from our scratch area
add rsp, 32 ; give back the stack space we used as scratch area

pop rbp ; standard "epilogue" to restore rsp
ret
如果只需要128字节(或更小)的暂存区,则无需这样做,因为这样我们就可以将红色区域用作暂存区。
另外,由于不再需要递减堆栈指针,因此可以将 rsp用作基本指针(而不是 rbp),从而不必保存和还原 rbp(在序言和结尾中),还可以释放 rbp以便使用作为另一个通用寄存器!
(从技术上讲,打开帧指针省略项( -fomit-frame-pointer,由于ABI允许,默认情况下启用 -O1)也将使编译器可以退出序言和结尾部分,具有相同的好处。但是,缺少红色区域,则无需调整堆栈指针以保留空间。)
但是请注意,ABI仅保证信号和中断处理程序之类的异步内容不会修改红色区域。调用其他函数可能会破坏红色区域中的值,因此它在叶函数(叶函数(那些不调用任何其他函数,就像它们在函数调用树的“叶子”中的那些函数)中一样没有特别有用。 。

最后一点: Windows x64 ABI deviates slightly from the AMD64 ABI used on other operating systems。特别是,它没有“红色区域”的概念。 rsp以外的区域被认为是 volatile 的,随时都可能被覆盖。取而代之的是,它要求调用者在堆栈上分配一个 home address space,然后在需要溢出任何寄存器传递的参数的情况下,供调用者使用。

关于assembly - 当我们有一个红色区域时,为什么我们需要堆栈分配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37941779/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com