x86-64上的红色区域究竟在哪里?

Sep*_*and 20 assembly x86-64 abi calling-convention red-zone

来自维基百科:

在计算中,红色区域是函数堆栈帧中超出返回地址的固定大小区域,该区域不被该函数保留.被调用函数可以使用红色区域来存储局部变量,而无需修改堆栈指针的额外开销.中断/异常/信号处理程序不会修改此内存区域.System V使用的x86-64 ABI要求一个128字节的红色区域,它直接在返回地址之后开始并包含函数的参数.OpenRISC工具链假设一个128字节的红色区域.

System V x86-64 ABI:

超出%rsp指向的位置的128字节区域被认为是保留的,不应被信号或中断处理程序修改.因此,函数可以将此区域用于函数调用不需要的临时数据.特别是,叶子函数可以将这个区域用于它们的整个堆栈帧,而不是调整序言和尾声中的堆栈指针.这个区域被称为红区.

  • 鉴于这两个引号,堆叠的返回地址上方或堆叠的返回地址下方红色区域 是?

  • 由于这个红色区域是相对的RSP,它是否向下push移动并且每个区域向上移动pop

fuz*_*fuz 15

鉴于这两个引号,堆叠的返回地址上方或堆叠的返回地址下方的红色区域是?

红色区域是128个字节的正下方rsp,即rsp - 128rsp - 1.

由于这个红色区域与RSP相关,每次推动它是否会向下移动并且每次弹出都会向上移动?

是.

  • @SepRoland:用户空间堆栈从不用于中断.内核不能信任它们.[内核代码必须使用`-mno-red-zone`进行编译,正是因为你提到的原因](http://stackoverflow.com/questions/25787408/amd64-abi-128-byte-red-zone),因为中断将RIP和RFLAGS推送到内核堆栈.顺便说一句,我刚刚在看到这个之前回答了这个问题:P (7认同)
  • @SepRoland硬件不知道红色区域.红色区域是软件的惯例,它的使用受到硬件可以做的限制.在函数调用期间不保留红色区域,因此您需要存储必须通过堆栈帧内的函数调用生存的数据或(暂时)降低堆栈指针.红色区域的整个目的是避免移动堆栈指针,因此这不是编译器会做的事情. (5认同)
  • @SepRoland它没有,参见 [这个答案](http://stackoverflow.com/questions/25787408/amd64-abi-128-byte-red-zone). (2认同)

Mic*_*tch 5

关于红区的维基百科文章是错误的,因此造成了歧义.

我在2017年4月修改了该文章以解决问题.截至该更新,维基百科文章内容如下:

在计算中,红色区域是函数堆栈帧中超出当前堆栈指针的固定大小区域,该区域不被该函数保留.被调用函数可以使用红色区域来存储局部变量,而无需修改堆栈指针的额外开销.中断/异常/信号处理程序不会修改此内存区域.System V使用的x86-64 ABI要求一个128字节的红色区域,它直接从堆栈指针的当前值开始.OpenRISC工具链假设一个128字节的红色区域

这使维基百科的文章更符合64位System V ABI定义.鉴于以上模糊性已解决,关于以下问题:

由于这个红色区域与RSP相关,每次推动它是否会向下移动并且每次弹出都会向上移动?

红区总是略低于128个字节RSP.随着RSP的变化(通过PUSH/POP/MOV等),红区的位置也是如此.