栈介绍&栈帧结构&堆栈操作

本文介绍了栈的基本概念,强调了栈在函数调用中的重要作用。栈帧结构是函数调用的核心,它包含了函数参数、局部变量和返回地址。文章详细讨论了Intel 32位体系中的寄存器分配,特别是EIP、ESP和EBP的作用。函数调用过程涉及到寄存器保存、栈帧创建和销毁,以及如何通过栈指针和帧指针访问函数信息。
摘要由CSDN通过智能技术生成

基本栈介绍

栈是一种典型的后进先出( Last in First Out )的数据结构,其操作主要有压栈(push)与出栈(pop)两种操作,如下图所示(维基百科)。两种操作都操作栈顶,当然,它也有栈底。

在这里插入图片描述

高级语言在运行时都会被转换为汇编程序,在汇编程序运行过程中,充分利用了这一数据结构。每个程序在运行时都有虚拟地址空间,其中某一部分就是该程序对应的栈,用于保存函数调用信息和局部变量。此外,常见的操作也是压栈与出栈。需要注意的是,程序的栈是从进程地址空间的高地址向低地址增长的

函数调用栈

程序的执行过程可看作连续的函数调用。当一个函数执行完毕时,程序要回到调用指令的下一条指令(紧接call指令)处继续执行。函数调用过程通常使用堆栈实现,每个用户态进程对应一个调用栈结构(call stack)。编译器使用堆栈传递函数参数、保存返回地址、临时保存寄存器原有值(即函数调用的上下文)以备恢复以及存储本地局部变量。不同处理器和编译器的堆栈布局、函数调用方法都可能不同,但堆栈的基本概念是一样的。

1.寄存器分配

寄存器是处理器加工数据或运行程序的重要载体,用于存放程序执行中用到的数据和指令。因此函数调用栈的实现与处理器寄存器组密切相关。Intel 32位体系结构(简称IA32)处理器包含8个四字节寄存器,如下图所示:

在这里插入图片描述

最初的8086中寄存器是16位,每个都有特殊用途,寄存器名城反映其不同用途。由于IA32平台采用平面寻址模式,对特殊寄存器的需求大大降低,但由于历史原因,这些寄存器名称被保留下来。在大多数情况下,上图所示的前6个寄存器均可作为通用寄存器使用。某些指令可能以固定的寄存器作为源寄存器或目的寄存器,如一些特殊的算术操作指令imull/mull/cltd/idivl/divl要求一个参数必须在%eax中,其运算结果存放在%edx(higher 32-bit)和%eax (lower32-bit)中;又如函数返回值通常保存在%eax中,等等。为避免兼容性问题,ABI规范对这组通用寄存器的具体作用加以定义(如图中所示)。

对于寄存器%eax、%ebx、%ecx和%edx,各自可作为两个独立的16位寄存器使用,而低16位寄存器还可继续分为两个独立的8位寄存器使用。编译器会根据操作数大小选择合适的寄存器来生成汇编代码。在汇编语言层面,这组通用寄存器以%e(A

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值