程序内存空间布局以及对栈顶,栈底的理解

一、程序的内存的空间布局:

栈 

由编译器自动分配释放管理。局部变量及每次函数调用时返回地址、以及调用者的环境信息(例如某些机器寄存器)都存放在栈中。新被调用的函数在栈上为其自动和临时变量分配存储空间。通过以这种方式使用栈,C函数可以递归调用。

需要由程序员分配释放管理,若程序员不释放,程序结束时可能由OS回收。通常在堆中进行动态存储分配。

 非初始化数据段(bss)

通常将此段称为bss段,这一名称来源于早期汇编程序的一个操作符,意思是“block started by symbol(由符号开始的块)”,未初始化的全局变量和静态变量存放在这里。在程序开始执行之前,内核将此段初始化为0。函数外的说明:long sum[1000] ; 使此变量存放在非初始化数据段中。

初始化的数据(data)

通常将此段称为数据段,它包含了程序中需赋初值的变量。初始化的全局变量和静态变量存放在这里。例如,C程序中任何函数之外的说明:int maxcount = 99; 使此变量以初值存放在初始化数据段中。

正文段(代码段)

CPU执行的机器指令部分。通常,正文段是可共享的,所以即使是经常环境指针环境表环境字符串执行的程序(如文本编辑程序、C编译程序、s h e l l等)在存储器中也只需有一个副本,另外,正文段常常是只读的,以防止程序由于意外事故而修改其自身的指令。

size命令可以看到一个程序的正文段(text)、数据段(data)、非初始化数据段(bss)及文件长度.

生长方向:对于堆来讲,生长方向是向上的,也就是向着内存地址增加的方向;

                  对于栈来讲,它的生长方向是自顶向下的,是向着内存地址减小的方向增长。

二、程序栈是什么样

程序执行/函数调用过程:

函数调用时:

        建立新栈帧,传递参数,修改“当前代码行”;

函数退出时:

        删除栈帧,处理返回值,修改“当前代码行”

过程调用 
        call   首先将被调函数的参数入栈,最后是返回地址入栈,再跳到被调函数起始地址
        leave  准备返回时的桢栈 : 令栈指针指向先指向当前桢的起始处(这里保存的是调用者桢的起始地),出栈(桢指针重置为调用者桢的起始;且栈指针指向返回地址)

       等同于 :   

       movl %ebp,%esp 
       popl %ebp
       ret    (栈指针指向返回地址)出栈并跳到那个位置(返回地址).

寄存器

(1) esp:栈指针寄存器(extended stack pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的栈顶。
(2) ebp:基址指针寄存器(extended base pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的底部。(ebp在当前栈帧内位置固定,故函数中对大部分数据的访问都基于ebp进行)
(3) eip:指令寄存器(extended instruction pointer),其内存放着一个指针,该指针永远指向下一条等待执行的指令地址。 可以说如果控制了EIP寄存器的内容,就控制了进程——我们让eip指向哪里,CPU就会去执行哪里的指令。eip可被jmp、call和ret等指令隐含地改变(事实上它一直都在改变)(ret指令就是把当前栈顶保存的返回值地址 弹到eip中)

函数栈帧的大小并不固定,一般与其对应函数的局部变量多少有关。函数运行过程中,其栈帧大小也是在不停变化的。eax一般用来保存函数的返回值,记住esp是栈顶指针寄存器,ebp是栈底指针寄存器。

esp中的指针将一直指向这个新位置, 所以 esp 中的地址数据是动态的。

三、入栈顺序

3.1 函数参数的入栈顺序:自右向左

        函数参数的入栈顺序和具体编译器的实现有关,一般采用自右向左的方式入栈,调用者清栈。
因为自右向左入栈顺序的好处就是可以动态的变化参数个数

void test(int a, int b, int c)  // 入栈顺序为cba,栈顶为a

3.2 局部变量的入栈顺序

        在没有栈溢出保护机制下编译时,所有局部变量按系统为局部变量申请内存中栈空间的顺序,即:先申请哪个变量,哪个先入栈,正向的。也就是说,编译器给变量空间的申请是直接按照变量申请顺序执行的。(先定义的先入栈
        在有栈溢出保护机制下编译时,入栈顺序有所改变,先按照类型划分,再按照定义变量的先后顺序划分,即:char型先申请,int类型后申请(与编译器溢出保护时的规定相关);然后栈空间的申请顺序与代码中变量定义顺序相反(后定义的先入栈)。

 

  • 13
    点赞
  • 74
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值