美文网首页
栈为什么要由高地址向低地址扩展?

栈为什么要由高地址向低地址扩展?

作者: 坠花湮没一朝风涟 | 来源:发表于2021-08-21 10:31 被阅读0次

原因

计算机内存分了代码段(.text段)、初始化的数据段(.data段)、未初始化的数据段(.bss段)、堆空间(heap)、栈空间(stack)和命令行参数和环境变量区域。

程序计数器(Program Counter,简称PC)的缺省指向0地址,计算机开机后从程序计数器指向的地址开始执行程序,每执行完一条指令后, 程序计数器自动加1。

因此很自然的,代码段从低地址区间开始加载,向高地址区间扩展;

heap从低地址向高地址扩展,做内存管理相对要简单些,为了避免栈空间和代码段冲突,最大利用地址空间,很自然的,我们会选择把栈底设置在高地址区间,然后让栈向下增长。

这是来自apue里一张经典的c程序内存分布图,着重看一下heap和stack的内存分布。

typical memory arrangement

栈由高地址向低地址扩展的优点

stack从高地址向低地址扩展,这样栈空间的起始位置就能确定下来。动态的调整栈空间大小也不需要移动栈内的数据,如果是从低地址到高地址的扩展,结尾的地址是固定的,如果要扩大或缩小,则需要移动整个栈的数据。

并且这样设计可以使得堆和栈能够充分利用空闲的地址空间。如果栈向上涨的话,我们就必须得指定栈和堆的一个严格分界线,但这个分界线怎么确定呢?平均分?但是有的程序使用的堆空间比较多,而有的程序使用的栈空间比较多。

所以就可能出现这种情况:一个程序因为栈溢出而崩溃的时候,其实它还有大量闲置的堆空间呢,但是我们却无法使用这些闲置的堆空间。所以呢,最好的办法就是让堆和栈一个向上涨,一个向下涨,这样它们就可以最大程度地共用这块剩余的地址空间,达到利用率的最大化!

现在 CPU 指令集的设计

大部分CPU指令集设计了函数调用架构,定义了专用的调用/返回指令,并在指令中隐含规定栈的方向。

  • 主流1:向低地址扩展:x86,MIPS
  • 主流2:自由选择:Arm(但个别指令仅支持向低)
  • 罕见:向高地址扩展:PA-RISC,操作系统Multics
  • 非主流:System z,栈是个链表[2]

如果CPU同时支持向上和向下,例如arm,那么编译器需要指定程序的调用方向,一般还是选择向下。比较罕见的极端的案例是Multics操作系统,这是Unix的巨无霸前身,设计者刻意选用向高地址扩展,因为该架构有助于防御缓冲区溢出攻击[3]。

引用

[1] What is the logical explanation for stacks typically growing downward and heaps growing upward?
[2] 列出了8种架构的栈增长方向 What is the direction of stack growth in most modern systems?
[3] 罕见的栈增长方向 Why does the stack grow downward?

相关文章

  • 栈为什么要由高地址向低地址扩展?

    原因 计算机内存分了代码段(.text段)、初始化的数据段(.data段)、未初始化的数据段(.bss段)、堆空间...

  • 《iOS面试题整理》- 堆和栈的区别

    内存分配方式 栈是高地址向低地址扩展, 是一块连续的内存区域、堆是地地址向高地址分配, 不连续的内存区域 栈是系统...

  • 2. 内存分配

    ==程序在内存空间分布为:== 由低向高 各个地址块 不连续 高地址 栈区(stack):由编译器自动分配释放 ,...

  • esp和ebp的在函数调用时的行为

    首先,高级语言的栈是从高地址向低地址增长的,为什么这样? 代码啥的在低地址,栈在高地址,这样就会向中间增长。 es...

  • app内存分配

    栈区(stack) 存储局部变量 概述:栈是向低地址扩展的数据结构,是一块连续的内存区域。由栈顶的地址和栈的最大容...

  • 栈溢出

    栈中压入数据栈顶指针地址变小 pop数据栈顶指针地址变大 也就是说栈底指针地址大于栈顶地址 EIP:扩展指令指针。...

  • iOS 的内存与存储区域

    1.栈区(stack)概述:栈是向低地址扩展的数据结构,是一块连续的内存区域。由栈顶的地址和栈的最大容量是系统预先...

  • 内存管理、自动释放池

    内存布局 栈(stack):方法调用,局部变量,是连续的,高地址向低地址扩展 堆(heap):通过alloc等分配...

  • iOS 内存概述

    在iOS中内存分为五大区域:栈去、堆区、全局区、常量区、代码区 栈区(Stack) 高地址向低地址扩展的系统数据结...

  • iOS逆向007--数据结构(一):堆栈、哈希表、时间复杂度、链

    堆和栈的区别 1、管理方式: 2、申请大小: 2.1 栈(stack):在Windows下,栈是向低地址扩展的数据...

网友评论

      本文标题:栈为什么要由高地址向低地址扩展?

      本文链接:https://www.haomeiwen.com/subject/iolfiltx.html