首页 > 解决方案 > 为什么 -fno-stack-protector 会颠倒这些字符串的存储顺序?

问题描述

我有以下功能:

void f(){
    char a[]="THIS IS A STR 1";
    char b[]="THIS IS A STR 2";
    char c[]="THIS IS A STR 3";
    char d[]="THIS IS A STR 4";
}

当我正常编译和运行这个程序时,这些字符串是这样分配在堆栈上的:

08 00 00 00 04 00 00 00 10 00 00 00 10 00 00 00 ................
10 71 c7 64 fc 7f 00 00 07 a9 90 7b 24 56 00 00 .q.d.......{$V..
54 48 49 53 20 49 53 20 41 20 53 54 52 20 31 00 THIS IS A STR 1.
54 48 49 53 20 49 53 20 41 20 53 54 52 20 32 00 THIS IS A STR 2.
54 48 49 53 20 49 53 20 41 20 53 54 52 20 33 00 THIS IS A STR 3.
54 48 49 53 20 49 53 20 41 20 53 54 52 20 34 00 THIS IS A STR 4.
a0 69 d9 76 c8 7f 00 00 00 dc ad e1 c7 89 e9 11 .i.v............
30 71 c7 64 fc 7f 00 00 37 a9 90 7b 24 56 00 00 0q.d....7..{$V..``

堆栈向更小的内存地址增长(在本例中为“向上”),因此这些字符串的存储顺序对我来说似乎是相反的。

而当我使用 -fno-stack-protector 编译和运行时,我得到了“正确”的顺序。

00 00 00 2e 10 00 00 00 08 00 00 00 05 00 00 00 ................
80 20 05 0f ff 7f 00 00 88 58 bb 32 96 55 00 00 . .......X.2.U..
54 48 49 53 20 49 53 20 41 20 53 54 52 20 34 00 THIS IS A STR 4.
54 48 49 53 20 49 53 20 41 20 53 54 52 20 33 00 THIS IS A STR 3.
54 48 49 53 20 49 53 20 41 20 53 54 52 20 32 00 THIS IS A STR 2.
54 48 49 53 20 49 53 20 41 20 53 54 52 20 31 00 THIS IS A STR 1.
a0 20 05 0f ff 7f 00 00 a4 58 bb 32 96 55 00 00 . .......X.2.U..
88 21 05 0f ff 7f 00 00 00 00 00 00 02 00 00 00 .!..............

我的印象是堆栈保护器所做的所有事情都放在堆栈金丝雀中,那么为什么它会像这样重新排列内存分配方式呢?

标签: cmemorystack

解决方案


当您有嵌套的函数或块时,堆栈“增长”的顺序是指不同堆栈帧的位置。它也将朝这个方向增长,需要在堆栈上动态分配临时对象。

然而,变量在栈帧中的位置是完全任意的;没有什么要求它与变量声明的顺序相同。编译器可能会在堆栈帧中重新排序变量的原因有很多。例如,具有较小对齐要求的变量可能会一起移动,以最小化填充。

这些字符串在您使用时被反转的事实-fno-stack-protector可能只是通过优化器的不同代码路径的副作用。我怀疑是否有任何具体原因,但这不重要。


推荐阅读