任务六:
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;
|