Chinaunix首页 | 论坛 | 博客
  • 博客访问: 511094
  • 博文数量: 52
  • 博客积分: 1223
  • 博客等级: 少尉
  • 技术积分: 751
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-23 21:32
文章分类

全部博文(52)

文章存档

2016年(1)

2015年(5)

2013年(1)

2012年(45)

分类: LINUX

2012-03-24 11:13:56

一、硬件完成的工作
1
set epc
2
set EXL 表示进入内核模式和禁止中断
3
set cause寄存器;有的异常也需设置BadVaddr寄存器
4
、跳到异常入口执行

二、软件工作

1
、区分不同的异常,Cause寄存器的ExcCode

2
、准备空间保存寄存器状态,由SAVE_ALL宏完成
说明几点:
1
)、获得空间方法如下:
若是用户态 --> 内核态,则 k0 = sp, sp = *kernelsp - PT_SIZEstore k0, PT_R29(sp),保存其它寄存器。

若是内核态
--> 内核态,直接 k0 = sp, sp = sp - PT_SIZEstore k0, PT_R29(sp),然后保存其它寄存器。

获得空间大小是PT_SIZE,寄存器按照特定的方式保存,形成一个 struct pt_regs 结构,传递给子函数。
2
)、在SAVE_ALL宏中,保存了epc,statuscause寄存器,这样就可以异常嵌套

3
、调用子函数(sp作为参数),做任何你想做的事。

4
、从子函数返回到ret_from_exception宏,ret_from_exception宏调用RESTORE_ALL宏完成寄存器状态的回复,最后恢复sp寄存器,即恢复到sp+PT_SIZE处。

5
eret,同时完成清除SREXL)位,把控制权交给epc指向的指令。

三、疑问探究

C
语言中主函数中调用子函数,栈的处理过程:

1
、进入子函数的时候,编译器完成sp - size
2
、子函数执行过程中,定义的变量会放到栈上,如果用到s0-s7寄存器,编译器会把s0-s7的值保存到栈上
3
、子函数返回时后,编译器先恢复
s0-s7寄存器,再将sp + 适当的size到进入子函数时sp处。

阅读(3374) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~