You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

栈中最后一个可访问地址之上的内存区域存储了什么?

用户栈顶部空白区域与起始地址疑问

之前我询问为何栈并非从0x7fff...c开始,得到的答复是通常0x800...及以上地址属于内核空间,命令行参数(cli args)和环境变量位于用户栈的顶部,因此栈起始地址低于0x7fff...c。但我最近通过测试发现了一些细节,想进一步探究:

C程序遍历栈字符串测试

我用以下程序尝试遍历栈上的所有字符串:

#include <stdio.h>
#include <string.h>
int main(int argc, const char **argv) {
  const char *ptr = argv[0];
  while (1) {
    printf("%p: %s\n", ptr, ptr);
    size_t len = strlen(ptr);
    ptr = (void *)ptr + len + 1;
  }
}

将程序编译为./t并运行,在显示完所有环境变量后,得到如下输出:

0x7ffc19f84fa0: <final env variable string>
0x7ffc19f84fee: _=./t
0x7ffc19f84ff4: ./t
0x7ffc19f84ff8: 
0x7ffc19f84ff9: 
0x7ffc19f84ffa: 
0x7ffc19f84ffb: 
0x7ffc19f84ffc: 
0x7ffc19f84ffd: 
0x7ffc19f84ffe: 
0x7ffc19f84fff: 

可以看到,./t字符串(地址范围0x7ffc19f84ff4~0x7ffc19f84ff7)的空终止符之后还有一个额外的空字节,随后程序触发段错误——我猜测此处就是栈的基址。那在内核内存开始前的这段“空白”区域中实际存储了什么?

汇编程序验证栈起始地址

我还尝试了以下汇编代码:

global _start
extern print_hex, fgets, puts, print, exit

section .text
_start:
  pop rdi
  mov rcx, 0
  _start_loop:
    mov rdi, rsp
    call print_hex
    pop rdi
    call puts
    
    jmp _start_loop

  mov rdi, 0
  call exit

其中print_hex是我自行编写的十六进制地址打印例程,运行后输出如下:

0x00007ffcd272de28
./bin/main
0x00007ffcd272de30
abc
0x00007ffcd272de38
def
0x00007ffcd272de40
ghi
0x00007ffcd272de48
make: *** [Makefile:47: run] Segmentation fault

看起来即使在_start入口处,栈也并非从0x7fff...开头的地址开始。

内容的提问来源于stack exchange,提问作者Pack Yak1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 17:01:06