浅谈栈帧(一)

好久没有更新了,最近打算把近期所学的内容更新一下

今天说一说内存栈帧方面的吧=。=

关于栈帧:首先我们呢来了解一下它的基本概念。

1.堆栈:对于堆栈,其实就是我们程序进行执行,那么我们必须给它一块地盘,有了地基,才能够建筑出我们所需要的东西。没有地我们是无法去干任何事情的。

在计算机中,这个地盘其实就对于我们的内存空间。我们的程序其实就相当于施工队伍。我们所给出命令。然后对其进行指挥,完成我们布置的任务。

(1)堆栈中有什么呢?

1.函数调用框架。

2.传递参数。

3.保存返回地址。

4.提供局部变量空间。

等等。

堆栈空间对应的是一段虚拟地址,这是关于计算机的寻址机制。

(2)那么堆栈是地盘,它的机构设计是怎么样的呢?

图片源于深入理解计算机系统:

其中需要进行了解的有:

堆栈相关的寄存器:

esp,堆栈指针(stack pointer),相当于栈帧中的栈顶。

ebp,基址指针(base pointer),相当于栈帧中的栈低。

对于这2个寄存器指针我们怎么理解呢?

其实我们可以认为这个就相当于我们盖楼楼层的地面与屋顶,当然。这个屋顶是根据需要可以动态变大的。我们利用两个之间的指向空间来进行我们当前物品(临时变量和函数变量)进行保存管理。

在ebp当前存储的是被保存的esp,因为在我们函数调用的过程中,其实就相当于我们盖楼的过程(在堆栈中,栈的空间是高地址到低地址的向下增长。)

ebp-4中保存的是我们的返回地址,当我们调用的函数执行完毕时候,我们通过利用这个赋值,来对ebp找到上一楼层的地面(上一调用函数的ebp所在地址。)

我们通过一段代码来进行解析一下:

#include <stdio.h>
void swap(int *a, int * b)
{
    int c;
    c = * a;
    * a = *b ;
    * b = c;
}

int main(void )
{
    int a;
    int b;
    int ret;
    a = 16;
    b = 64;
    ret = 0;
    ret=swap(&a, &b);
    return ret;
}

上面这段代码就是简单的一个函数调用,我们通过Linux来看一下他的汇编代码。

下面是swap函数的:

其中esp,ebp就相当于我们的通知跳转值,毕竟楼再高也必须有个限度好么,要不,你是要上天?

堆栈操作:

上文中的push,栈顶地址减少4个字节。

pop,栈顶地址增加4个字节。

不难理解,其实就相当于我们楼层的电梯呗,不过你下去了,楼层就销毁了(针对于操作ebp,esp而言奥。)

栈帧其实就是这样,然后我们来看两段程序分析一下为什么会出现这样的结果:

Linux平台下:

#include<stdio.h>
#include<stdlib.h>

void bug()
{
	system("reboot");
	exit(0);
}

int stack_test(int a,int b)
{
    //int* p = &a;
    //p--;
    //*p = bug;
	printf("before writer : 0x%x\n",b);
	int *p = &a;
	p++;
	*p = 0xdddd;
	printf("after write : 0x%x\n",b);
	int c  = 0xcccc;
	return c;
}

int main()
{
	int a = 0xaaaa;
	int b = 0xbbbb;
	int ret = stack_test(a,b);
	printf("you should run here\n");
	return 0;
}

其实对应的图就是:

然后我们看代码:

        printf("before writer : 0x%x\n",b);
    	int *p = &a;
	p++;
	*p = 0xdddd;
	printf("after write : 0x%x\n",b);
	int c  = 0xcccc;
	return c;

让p指针指向了&a,在临时变量中,然后p++就跳转到了&b上,然后我们修改*p,导致b的值变为了

0xdddd;

接下来:

    int* p = &a;
    p--;
    *p = bug;

这个一样的,p指针只上了传递的临时变量&a,然后p--就跳转到了返回地址,然而我们将返回地址赋值到了bug函数上,那么就出现我们不是跳转到main函数中,而是执行了bug函数中的重启命令。

未完待续...

时间: 2024-11-05 12:07:01

浅谈栈帧(一)的相关文章

浅谈栈帧(二)

接上一篇:浅谈栈帧(一) 上一篇我们简单说了一下关于堆栈与栈帧调用函数是如何调用的,堆栈中的数据是如何存储在内存中的,用了几个简单的实例去观察分析他. 这篇,我们从根本来思考一下堆栈这种东西: 其实在计算机的早期,电脑的内存是用是十分老实的,没错就是老实.他没有进行一些内存空间上的保护. 大家想想,在当内存空间不存在保护时,我们利用一个函数不断去改写计算机本身的内存,然后导致缓冲区溢出.这将使电脑崩溃,无法使用.因为内存不存在狡兔三窟,所以就老老实实的被病毒所平推了,就是是强拆,所以强拆是多么的

浅谈“栈和堆”

对于一些新人可能会不理解栈和堆是什么,在这里我简单介绍一下: 程序运行时,它的数据必须存储在内存中.一个数据项需要多大的内存.存储在什么地方.以及如何存储都依赖与该数据项的类型. 运行中的程序使用两个内存区域来存储数据:栈和堆. 首先,什么是“栈”? 栈是一个内存数组,是一个LIFO(last-in  first-out,后进先出)的数据结构.栈存储几种类型的数据: 某些类型变量的值 程序当前的执行环境 传递给方法的参数 栈的特征: 栈有如下几个普遍特征: 数据只能从栈的顶端插入和删除 把数据放

浅谈栈&amp;&amp;进制转换

利用stack实现进制转换 Stack.h #ifndef _STACK_H_ #define _STACK_H_ #include<iostream> #include<assert.h> using namespace std; typedef int ElemType; #define STACK_MAX_SIZE 100 #define HEX 2 typedef struct Stack { ElemType *base;//栈底指针 int top; //栈顶标识 in

浅谈栈、队列

所谓栈和队列其本质都是一种存储信息的方法,最主要的差别就是两者的存取方式不同,栈相当于是一个一端开口一端封闭的空心玻璃柱,每存入一个数据就是扔进一个与管口等粗的球,取出数据时只能取最上头的,也就是最后一个放进去的,并且当管中无球时,无法取数据:相对而言,队列相当于是一个两端开口的空心玻璃柱,每存入一个数据,就从后端插入一个与管口等粗的球,取数据时只能从前端取不能从后段取,同样当其中无球时无法取. 从上述介绍中可以发现两者各有优势,但队列有一个显著问题,但插入取出次数多时,可能仅有几个数据但存储却

浅谈栈

所谓栈,就是一种先进后出的数据结构. 何为先进后出?想象一个箱子,你往箱底塞了一本语文书,然后往语文书上放数学书.假设箱子底面积与书的面积相同,那么你想把先放进去的语文书拿出来,就必须得先把放在上面的数学书拿出来.所以"先进"的语文书与数学书比较是"后出"的. 在代码中一个栈由一个数组\(stk\)和一个变量\(top\)组成,数组存信息,\([1,top]\)的空间都被占用了,下一次放元素就只能放在\(top+1\)这个位置然后让\(top=top+1\).拿元素

浅谈栈和队列

### 栈 栈模型 栈(stack)是限制对元素的插入(push)和删除(pop)只能在一个位置上进行的表,该位置是表的末端,叫做栈的栈顶(top). 栈的基本操作只有两种,压入栈(push)和弹出栈顶(pop),且只能作用于栈顶.(只有栈顶元素是可访问的 你可以把栈结构理解成一个底部封闭,顶部打开的桶.最先进去的元素一定是最后才能取出,最晚进去的元素一定是最先取出. 因此栈又叫做LIFO(后进先出,Last In First Out)表. 栈的优势 栈的操作是常数时间的,而且是以非常快的常数时

浅谈main函数的栈帧

要理解什仫是栈帧首先就要理解什仫是栈? 那仫什仫是栈呢?在数据结构中有一种结构叫栈,它的定义为:仅在表尾进行插入和删除的操作 我们允许插入和删除的一端称为栈顶(esp),另一端则为栈底(ebp),所以栈又被称为后进先出的线性表(LIFO).而且我们知道在内存中空间的分配是从高地址向低地址增长的; 好了说了这仫多的栈那仫什仫是栈帧呢?其实说白了栈帧实际上就是用来记录函数调用过程的信息,是编译器用来实现函数调用过程的的一种数据结构.下图是我对栈帧分布的一点理解,以下都是在VC++6.0版本下测试的:

浅谈C#中堆和栈的区别(附上图解)

线程堆栈:简称栈 Stack 托管堆: 简称堆 Heap 使用.Net框架开发程序的时候,我们无需关心内存分配问题,因为有GC这个大管家给我们料理一切.如果我们写出如下两段代码: 代码段1: public int AddFive(int pValue) { int result; result = pValue + 5; return result; } 代码段2: public class MyInt { public int MyValue; } public MyInt AddFive(i

浅谈算法和数据结构(1):栈和队列

浅谈算法和数据结构(1):栈和队列 2014/11/03 ·  IT技术                                         · 2 评论                                      ·  数据结构, 栈, 算法, 队列 分享到: 60 SegmentFault D-Day 2015 北京:iOS 站 JDBC之“对岸的女孩走过来” CSS深入理解之relative HTML5+CSS3实现春节贺卡 原文出处: 寒江独钓   欢迎分享原创