ucore lab1 任务六
任务六:
1.首先要明白什么是函数调用堆栈(上网查资料)
分析下述代码的堆栈调用
int Add(int x, int y)
{
return x + y;
}
void main()
{
int *pi = new int(10);
int *pj = new int(20);
int result = 0;
result = Add(*pi,*pj);
delete pi;
delete pj;
}
在程序执行过程中系统如何进行呢? 1.在堆中创建10和20的区域 在栈中压入*pi,*pj和result进行 2.调用ADD函数进行操作 在栈创建10,20和30空间分别用来存a,b,和a+b 3.调用函数结果送给result其他创建空间消失 所以我们发现函数的调用并不像我们以前逻辑上想象的那样简单 ,首先要进行压栈的操作 |
以上就是有关网上关于函数堆栈的简要讲解. * 阅读实验指导书后发现,我们完成这个函数其实很简单的只需要调用几个函数就行了,补充源代码如下 print_stackframe(void) { /* LAB1 YOUR CODE */ uint32_t ebp = read_ebp(); //读取当前ep寄存器的值 uint32_t eip = read_eip(); //读取当前 IP寄存器的值 uint32_t arg1; //下面设置几个用来存储参数值的变量 uint32_t arg2; uint32_t arg3; uint32_t arg4; while(ebp != 0) { //根据实验指导书的提示,边界条件为ebp == 0 memcpy(&arg1,ebp+8,4); //获取第一个参数的值 memcpy(&arg2,ebp+12,4); memcpy(&arg3,ebp+16,4); memcpy(&arg4,ebp+20,4); cprintf("ebp: %x eip:%x args %x %x %x %x",ebp,eip,arg1,arg2,arg3,arg4); print_debuginfo(eip); memcpy(&eip,ebp+4,4); memcpy(&ebp,ebp,4); } } 运行结果为: |
分析最后一行为: <unknow>: -- 0x00007d67 – 通过分析我们写的程序可以知道,我们程序返回的条件就是根据下面的提示写出的: Note that, the length of ebp-chain is limited. In boot/bootasm.S, before jumping to the kernel entry, the value of ebp has been set to zero, that's the boundary. 说明我们打印出来的最后一句话,ebp含义就是指向ebp为0的内存单元的内存地址,eip就是第一个函数返回地址,其余为调用的参数。
任务七: 1.中断向量表中一个表项占用多少字节? 2.完成初始化函数idt_init 3.完成中断处理函数trap() 实验过程: 中断向量表中一个表项的代码为: struct gatedesc { unsigned gd_off_15_0 : 16; // low 16 bits of offset in segment unsigned gd_ss : 16; // segment selector unsigned gd_args : 5; // # args, 0 for interrupt/trap gates unsigned gd_rsv1 : 3; // reserved(should be zero I guess) unsigned gd_type : 4; // type(STS_{TG,IG32,TG32}) unsigned gd_s : 1; // must be 0 (system) unsigned gd_dpl : 2; // descriptor(meaning new) privilege level unsigned gd_p : 1; // Present unsigned gd_off_31_16 : 16; // high bits of offset in segment }; 将bit位相加共64bit为8字节。 设置函数: 首先打开新加入的文件中,寻找中断向量表 MMU.H中的SETGATE宏进行填充 #define SETGATE(gate, istrap, sel, off, dpl) { \ 说明如下: /* * 下面就是有关参数的寻找了,主要使用这个宏进行段选择符的构造 gate:这是为相应的idt数组内容 istrap:系统段设置为1,中断门设置为0 off:为__vectors数组内容 dpl:设置优先级 使用__vector数组时,c程序文件中引用之前,extern声明一下 extern long __vectors[]; /* LAB1 YOUR CODE */ 设置时钟进行操作: char c; |
ucore lab1 任务六相关推荐
- 《ucore lab1 练习5》实验报告
[练习5]实现函数调用堆栈跟踪函数 我们需要在lab1中完成kdebug.c中函数print_stackframe的实现,可以通过函数print_stackframe来跟踪函数调用堆栈中记录的返回地址 ...
- ucore lab1 实验报告
UCORE LAB1 实验报告 练习一 理解通过make生成执行文件的过程 1.操作系统镜像文件ucore.img是如何一步一步生成的? 先打开lab1文件夹下的Makefile,查看里面的代码,在各 ...
- 操作系统 ucore lab1
操作系统 ucore lab1 实验目的 操作系统是一个软件,也需要通过某种机制加载并运行它.在这里我们将通过另外一个更加简单的软件-bootloader来完成这些工作.为此,我们需要完成一个能够切换 ...
- 操作系统实验—ucore Lab1
一.内容 通过 Lab1 中的 bootloader 可以从实模式切换的保护模式,然后再读取磁盘并加载 ELF 文件以加载 OS 操作系统,操作系统能够读入字符并显示到屏幕上,具体内容如下: 练习 1 ...
- 操作系统ucore lab1实验报告
操作系统lab1实验报告 [练习1] 理解通过 make 生成执行文件的过程.(要求在报告中写出对下述问题的回答) 在此练习中,大家需要通过阅读代码来了解: 1. 操作系统镜像文件 ucore.img ...
- 《ucore lab1 exercise5》实验报告
资源 ucore在线实验指导书 我的ucore实验代码 题目:实现函数调用堆栈跟踪函数 我们需要在lab1中完成kdebug.c中函数print_stackframe的实现,可以通过函数print_s ...
- 操作系统 ucore lab1 练习2-6
[练习2] 使用qemu执行并调试lab1中的软件 进行如下的小练习: 从CPU加电后执行的第一条指令开始,单步跟踪BIOS的执行. 在初始化位置0x7c00设置实地址断点,测试断点正常. 从0x7c ...
- ucore lab1
[练习1] [练习1.1] 操作系统镜像文件 ucore.img 是如何一步一步生成的?(需要比较详细地解释 Makefile 中每一条相关命令和命令参数的含义,以及说明命令导致的结果) 输入make ...
- ucore lab1学习笔记整理
前置知识 ucore是运行在80386这一32位x86架构的CPU,汇编采用的格式是AT&T, lab1 ucore开始执行makefile会生成磁盘映像,这个磁盘映像就是对应着现实计算机中的 ...
最新文章
- 在幕后看看Swift中的Map,Filter和Reduce的实现
- 学习笔记:部署趋势科技企业安全无忧版——服务器端和web控制台的安装(一)...
- Tree Recovery--POJ 2255
- 毕业设计(二十四)---退出 博客 清除session
- [译]5步实现Silverlight中的Command
- C++中数学运算、比较、赋值操作符的重载
- 六、张正友标定法小结
- com.mysql.cj.exceptions.InvalidConnectionAttributeException
- oracle 日志丢失,Oracle联机日志文件丢失解决方法一例
- mysql时间间隔interval_MySQL DATEDIFF函数获取两个日期的时间间隔的方法
- zabbix监控nginx连接数
- 64位Java开发平台的选择,如何区分JDK,Tomcat,eclipse的32位与64版本
- 美国参议院紧急通过关键基础设施网络安全法案
- multism中ui和uo应该怎么表示_第310 这四个常考英语单词,到底表示时间还是地点?...
- 论网络工程中,系统开发设计可行性研究及市面产品对比!
- scanf函数读取缓冲区数据的问题
- 三大方面解析虚拟化技术在云计算数据中心中的应用
- 免费版本在线客服迷你窗口内的开场广告语如何关闭?
- 我沪漂 16 年,再也不打工了!
- RS-485(物理层) 硬件接口