实验5--实现函数调用堆栈跟踪函数
需要完成kdebug.c中函数print_stackframe的实现,可以通过函数print_stackframe来跟踪函数调用堆栈中记录的返回地址。
一.函数堆栈
  主要的两点在于栈的结构和ebp寄存器的作用。一个函数调用动作可分解为:零到多个PUSH指令(用于参数入栈),一个CALL指令。CALL指令内部其实还暗含了一个将返回地址(即CALL指令下一条指令的地址)压栈的动作(由硬件完成)。几乎所有本地编译器都会在每个函数体之前插入类似如下的汇编指令:
   
  这样在程序执行到一个函数的实际命令前,已经有以下数据顺序入栈:参数,返回地址,ebp寄存器。   
  函数调用的步骤:
    1.参数入栈:将参数从右向左依次压入栈中。  
       2. 返回地址入栈:call指令内部隐含的动作,将call的下一条指令入栈,由硬件       完成。  
       3. 代码区跳转:跳转到被调用函数入口处。  
       4. 函数入口处前两条指令,为本地编译器自动插入的指令,即将ebp寄存器入栈,       然后将栈顶指针esp赋值给ebp。
  相反的,函数返回的步骤为:
    1.保存返回值,通常将函数返回值保存到寄存器EAX中。  
       2. 将当前的ebp赋给esp。  
       3. 从栈中弹出一个值给ebp。  
       4. 弹出返回地址,从返回地址处继续执行。
  并且在函数调用过程中的ebp起着关键作用,从该地址向上(栈底方向)能依次获取返回地址、参数值,向下(栈顶方向)能获取函数局部变量值,而该地址处又存储着上一层函数调用时的ebp的值,于是以此为线索可以形成递归,直至到达栈底。这就是函数调用栈。
 
二.print_stackframe函数的实现
  由以上知识和源代码文件中的注释实现print_stackframe():
   
  执行’make qemu’指令得到的结果为:
   
  可以观察到显示结果与实验指导书上一致。对于最后一行:其对应的是第一个调用堆栈的函数,即bootmain.c中的bootmain函数,因为bootloader设置的堆栈从0x7c00开始,执行’call bootmain’转入bootmain函数。其ebp=0x00007bf8,此时的eip=0x00007d6e,其压入的4个参数分别为0xc031fcfa, 0xc08ed88e, 0x64e4d08e, 0xfa7502a8。

ucore-lab1-练习5report的更多相关文章

  1. 《ucore lab1》实验报告

    资源 ucore在线实验指导书 我的ucore实验代码 练习1:理解通过make生成执行文件的过程 详见<ucore lab1 exercise1>实验报告 练习2:使用qemu执行并调试 ...

  2. ucore lab1 bootloader学习笔记

    ---恢复内容开始--- 开机流程回忆 以Intel 80386为例,计算机加电后,CPU从物理地址0xFFFFFFF0(由初始化的CS:EIP确定,此时CS和IP的值分别是0xF000和0xFFF0 ...

  3. 《ucore lab1 exercise5》实验报告

    资源 ucore在线实验指导书 我的ucore实验代码 题目:实现函数调用堆栈跟踪函数 我们需要在lab1中完成kdebug.c中函数print_stackframe的实现,可以通过函数print_s ...

  4. 《ucore lab1 exercise3》实验报告

    资源 ucore在线实验指导书 我的ucore实验代码 题目:分析bootloader进入保护模式的过程 BIOS将通过读取硬盘主引导扇区到内存,并转跳到对应内存中的位置执行bootloader.请分 ...

  5. 《ucore lab1 exercise2》实验报告

    资源 ucore在线实验指导书 我的ucore实验代码 题目:使用qemu执行并调试lab1中的软件 为了熟悉使用qemu和gdb进行的调试工作,我们进行如下的小练习: 从CPU加电后执行的第一条指令 ...

  6. 《ucore lab1 exercise1》实验报告

    资源 ucore在线实验指导书 我的ucore实验代码 题目:理解通过make生成执行文件的过程 列出本实验各练习中对应的OS原理的知识点,并说明本实验中的实现部分如何对应和体现了原理中的基本概念和关 ...

  7. ucore操作系统学习笔记(一) ucore lab1系统启动流程分析

    一.ucore操作系统介绍 操作系统作为一个基础系统软件,对下控制硬件(cpu.内存.磁盘网卡等外设),屏蔽了底层复杂多样的硬件差异:对上则提供封装良好的应用程序接口,简化应用程序开发者的使用难度.站 ...

  8. Ucore lab1实验报告

    练习一 Makefile 1.1 OS镜像文件ucore.img 是如何一步步生成的? + cc kern/init/init.c + cc kern/libs/readline.c + cc ker ...

  9. ucore lab1练习2 qemu+gdb 不能协作调试的问题make lab1-mon

    本练习是qemu结合gdb调试,但是我做实验的时候并不能像视频输入make lab1-mon那样顺利调试,期间有各种error,后来我找到原因,请看解决方法. 请先把ucore_lab文件删除,以下全 ...

  10. 《ucore lab1 exercise4》实验报告

    资源 ucore在线实验指导书 我的ucore实验代码 题目:分析bootloader加载ELF格式的OS的过程 通过阅读bootmain.c,了解bootloader如何加载ELF文件.通过分析源代 ...

随机推荐

  1. 我的代码-cleaning

    # coding: utf-8 # In[18]: import pandas as pdimport numpy as npfrom sklearn import treefrom sklearn. ...

  2. 谈一谈Crsf和XSS攻击

    crsf 和 XSS CRFS攻击全称是一种利用cookie的漏洞进行的一种跨域请求伪造: 攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一 ...

  3. s2第六章继承和多态

    public class Employee { //年龄 public int Age { get; set; } //性别 public Gender Gender { get; set; } // ...

  4. Django请求流程图

    Django请求流程图

  5. lvs UDP端口负载均衡配置

    ! Configuration File for keepalived global_defs { notification_email { test@163.com } notification_e ...

  6. varchar字数

    每行数据最多65000字节 长度是当前字符集的字符长度,而不是字节长度! 参考:https://www.cnblogs.com/billyxp/p/3548540.html 经常变化的字段用varch ...

  7. RabbitMQ 死信队列 延时

    package com.hs.services.config; import java.util.HashMap; import java.util.Map; import org.springfra ...

  8. ClassNotFoundException与NoClassDefFoundError异常

    方法 loadClass()抛出的是 java.lang.ClassNotFoundException异常(一般是jar冲突或者没有引入jar):方法 defineClass()抛出的是 java.l ...

  9. Python递归解压缩多级.zip压缩包

    参考如下代码(from:https://stackoverflow.com/questions/36285502/how-to-extract-zip-file-recursively-in-pyth ...

  10. DataTable.Select 处理关联表数据

    DataSet.Clone  会拷贝表结构,关联关系也会拷贝, 用Select 筛选后ImportRow 导入新的DataTable,然后处理关联DataTable DataSet ds2 = dsS ...