c-在函数中用作局部变量时,为什么数组不在堆栈方向上增长



这可能是一个愚蠢的问题,但我想知道如果数组中填充了值,使其朝堆栈的方向增长会怎么样(因此,在数组是唯一一个局部变量的情况下,使得数组的第一个元素在堆栈帧指针/基指针后一个字节寻址,第二个元素在堆叠帧指针/基址指针后两个字节寻址…(,它不会让C中的堆栈溢出更安全吗?因为返回地址不能那么容易地被覆盖(数组必须填满几乎整个RAM,因此程序会崩溃,而不是执行一些恶意代码(?

如果不完全交换所有数组的寻址模型,就无法对不断增长的堆栈执行此操作。这是一个可行的实现选择,但与现有的ABI不兼容。

您注意到,在某些方面,拥有一个向上增长的堆栈(其中向上是正数组索引的方向(在某些方面比拥有一个向下增长的堆栈更安全。然而,这并没有那么安全。考虑一下当您将具有自动存储功能的数组的地址传递给另一个函数时会发生什么。被调用者在堆栈上的位置将高于数组,因此数组的任何溢出都将溢出到被调用者的堆栈帧中,可能包括其返回地址。例如:

void foo()
{
char s[4];
strcpy(s, "hello world");
}

strcpy返回时,它的返回地址可能已经被存储到其地址被传递给它的数组的末尾而被破坏

"堆栈的方向"是实现的函数,而不是语言——语言规范甚至不假设存在堆栈。

数组索引的工作原理是向基地址添加非负偏移量,并取消对结果的引用——无论堆栈的增长方向如何,数组都必须朝着不断增加的地址"向上"增长。

真正使数组操作安全(r(的唯一方法是C语言规范要求对所有数组访问进行边界检查,并对越界访问抛出异常。当然,C语言规范还必须添加结构化异常处理(当前的信号处理方法将严重不足(。

这样的添加…不太可能。

最新更新