关于栈——不针对特定实现的分析

  1. 区分硬件栈和堆栈

    • 堆栈是C语言编译器以及OS上程序内存结构的抽象概念,在CPU上只有寄存器、内存、数据(包括地址数据)。
    • 硬件栈: 一般CPU会有一个到多个的栈指针寄存器和特殊的栈操作汇编指令,是用于过程调用以及中断切换的时候保存上下文的(特别是返回地址)。
      • Intel x86 IA32 等好像都是 FD,ARM 虽然说可以调整方式(不确定细节),但是他的 ATPCS 还是要求用 FD。
  2. 区分堆栈中的堆和栈
    一般说堆是动态分配内存的管理结构;
    一般说栈是指函数调用栈,是以“栈帧”(stack frame)为单位的;
    每个栈帧是一个函数调用,包含了返回地址(ARM-LR & x86-CS:IP),上下文环境(寄存器),函数参数,以及 C 编译器自动管理的局部 auto 变量;
    PS0: 栈帧的相对位置,栈帧的结构,局部变量的相对位置,以及实际参数的相对位置是由实现决定的,不同的 OS & CPU 甚至是 Complier 可以有不同的实现;
    PS1: 这里其实忽略了寄存器的存在,栈帧上的值可能不会存放在栈而是直接放在寄存器里;
    PS2: 据我所知 ARM 有自己的过程调用标准 ATPCS,他传递参数以及返回值就是放在寄存器的;
    PS3: C标准只要求,C对象是连续且对齐的内存块,以及指向 C对象的指针是组成对象的字节的连续地址中的最低那个;C对象都可以取地址(包括struct返回值?不确定),但是不知道标准有没有说,允许被优化到寄存器中。

  3. 虚拟进程地址空间
    NT & linux 的每一个进程都有自己的进程空间,是虚拟的分页的。
    在这个进程空间中的每一个线程都有自己的函数调用栈。
    这个进程空间结构是操作系统决定的。

在和yyf的辩论中,发现:如果想要分析某一个实现下的程序的内存布局,可能要先明确下面的概念

  1. 表述中严格区分堆栈中的堆和栈,否则很容易说混;
  2. 区分地址空间的 上下 和 高地址端和低地址端;
  3. 严格区分大小端
    要不很难分析清楚并表述出来。

请指正。

原文地址:https://www.cnblogs.com/tjua/p/7799761.html