如果我在堆栈帧中插入新的函数和指令来汇编 x86 代码,是否有必要增加堆栈大小?如果是的话是多少?
sub 0x4, %esp
push %eax ;;new instruction
...
call fun ;; new inserted function
pop %eax ;;new instruction
.....
add 0x4, %esp
如果我在堆栈帧中插入新的函数和指令来汇编 x86 代码,是否有必要增加堆栈大小?如果是的话是多少?
sub 0x4, %esp
push %eax ;;new instruction
...
call fun ;; new inserted function
pop %eax ;;new instruction
.....
add 0x4, %esp
调用约定是管理如何调用函数、传递和返回值以及如何管理堆栈空间和可用寄存器的关键。有很多约定。知道你的函数使用的是哪一个,你调用的函数使用的是哪一个;他们可能不一样!
一个非常常见的约定是“管理你自己的堆栈”。在这种情况下,每个函数都会在堆栈上分配所需的堆栈空间量。它不需要担心它调用的函数的堆栈空间需求;根据定义,他们将分配他们需要的(额外的)堆栈空间。
“叶”函数是不调用其他函数的函数;每个叶子函数都需要一些堆栈空间。一些调用约定要求叶函数的调用者不仅为其自身需要分配空间,而且为其调用的所有叶函数分配空间。这将调用叶函数(被调用最多!)的开销降至最低。通常这种安排只由编译器完成,因为人们很难可靠地跟踪他们调用的所有函数以及这些函数的堆栈需求。有时您可能会遇到一个手写的汇编函数,该函数在其 API 中声明调用者必须为其分配空间。
System V ABI 在 SP 下方提供了一个大约 128 字节堆栈的“红色区域”,这些堆栈始终可供叶函数使用。这意味着调用者不需要分配该空间,并且小于红色区域大小需求的叶函数只需使其可用而不分配它。这是一个非常好的约定,因为没有函数不必担心它是否正在调用叶函数,这使得可以将任意组例程链接在一起。