zoukankan      html  css  js  c++  java
  • 汇编与栈帧学习(一)

    最近学习《深入理解计算机系统》,书中全是汇编,正好借着GDB来研究一下汇编语言和函数调用时栈帧的变化。于是写下这个开篇的博客,我先以一个简单的程序进行研究:

    如上图这个程序(func.c)含有两个函数。main和add,功能很简单就是求两个两个数的和然后输出。

    用命令:gcc func.c -o func.o 编译成目标文件func.o。用GDB加载:

    首先在main和add两处设置了断点。为了便于观察程序运行时栈帧的变化。之后运行程序,对main进行反汇编看一下main的汇编程序。

    如上所示,断点在地址0x08048436停住了(这行没有执行),可以看出加载进来运行后已经执行了两条指令。即将ebp压栈,令ebp 和 esp指向同一个内存。

    这时可以看一下在ebp中的值是0xbffff0e8,和栈帧的一些信息。

    输入了3次ni命令(ni命令是每次执行一个语句),所以这时程序执行到了0x08048444停住了。因为需要存储一些参数,所以程序分配了32字节来分配空间,然后将在main函数里的两个值传入到分配好的空间中。即将10 和 8 分别存入0x4(esp),即这个参数10存储在内存地址为0xbffff0c4里和0x8(esp)处(8存在内存地址为0xbffff0c8里)

    同理。一次执行一条指令。执行了两次进入了add函数的栈帧。以此同时在这个栈帧里已经把空间分配好了。在0x08048423处指令表示分配16个字节这个函数使用。

    上图是两次ebp和esp的变化。上边是main栈帧下面是add栈帧。之后继续逐条运行程序产生下面的结果:

    通过读这个汇编程序。第四条看出将0xc(%ebp)里的值存入寄存器%eax中。通过计算可以知道0xc(%ebp)的地址就是0xbffff0c4。 即我们在main栈帧中存放参数10的地址,也就是将10存入eax寄存器中。同理将8存放到edx寄存器中。对两个寄存器相加存入eax,同时将结果存入0xbffff0b4中。返回。

    如上图。返回后,在main栈帧中继续执行。来到了0x08048450处,这时ebp和esp值有恢复成了main栈帧中的值。继续执行程序。执行完后会有如下结果:

    上边的程序看到将结果存入到0x1c(%esp)处的内存处,然后调用printf的库函数,进行输出结果。结束。

  • 相关阅读:
    《企业虚拟化应用实战》笔记
    s3c2440笔记1(启动)
    reactor & proactor 笔记
    交换机选型笔记
    Intel VT-x 基本概念
    note of introduction of Algorithms(Lecture 3
    STC12C5A60S2笔记8(串口)
    STC12C5A60S2笔记7(定时器)
    bzoj 3242: [Noi2013]快餐店 章鱼图
    高精度模板
  • 原文地址:https://www.cnblogs.com/dormant/p/5059644.html
Copyright © 2011-2022 走看看