异常

异常

什么是异常

异常是异常控制流的一种形式,它一部分由硬件实现,一部分由操作系统实现。因为它们有一部分是由硬件实现的,所以具体细节将随系统的不同而有所不同。然而,对于每个系统而言,基本的思想都是相同的。

大致如下:
在这里插入图片描述

异常控制流

下述程序中的write和_exit函数就进行了系统函数的调用:

// hello world
int main()
{
 	write(1, "hello, world\n", 13);
	_exit(0);
}

其对应的汇编为:

.section .data
 	string:
 		.ascii "hello, world\n"
 	string_end:
		.equ len, string_end - string
 	.section .text
 	.globl main
main:
	First, call write(1, "hello, world\n", 13)
	movq 	$1, %rax 	  write is system call 1
	movq 	$1, %rdi 	  Arg1:stdout has descriptor 1
	movq 	$string, %rsi Arg2:Hello world string
	movq 	$len, %rdx    Arg3:string length
	syscall     	  Make the system call
	Next, call exit(0)
	movq 	$60, %rax 	  _exit is system call 60
	movq 	$0, %rdi      Arg1:exit status is 0
	syscall 		  Make the system call

操作系统的系统调用,在汇编中是使用寄存器进行参数传递

与过程之间的参数调用类似,操作系统的系统调用,同样使用了6个寄存器来传递参数,但寄存器的使用与caller的有所不同。操作系统的系统调用,使用了%rdi,%rsi,%rdx,%r10,%r8,%r9这六个寄存器,并以%rax作为返回值

处理器的状态:在CPU中有状态寄存器,会标识处理器的状态。处理器的状态一旦发生重要变化,则称之为事件。事件会发出请求信号,以告诉CPU,称之为中断请求。处理中断请求——由事件引起了异常,使控制流发生了变化。原本控制流应该是在执行用户写的程序,而发生异常后,去执行了另外的程序——异常处理程序。

事件并不一定与当前执行的指令有关。例如,访问时发现数据不在内存中时,就引起了异常,由异常处理程序将需要的数据从辅存调往主存,这是与执行有关的事件。而ctrl+C强制中断,则与当前执行的指令无关。

异常处理程序属于操作系统的一部分。一旦执行完处理程序后,还要回到原来的代码中继续执行。返回的位置根据执行的结果而定,
  1、可能会回到引起异常的指令上,重新执行,
  2、也可能会返回到引起异常的指令的下一条指令。当前指令执行完后,停下来去执行异常处理程序,写入到CPU中。
  3、还可能是程序完全被中断(例如蓝屏、死机),此时机器出了问题,异常处理程序已经解决不了了

异常表

异常的编号从0——255,每个编号对应一个异常处理程序。在操作系统中,专门有一张称为异常表的表(有时也称作中断向量表),一共有256项。每个表项中存放的是对应的异常处理程序的入口地址。这张表是常驻内存的,由专有寄存器去找到那个表

在64位机下,每次都是将异常编号乘以8来找到对应的地址

内核栈

异常处理程序运行在内核模式下,可以访问所有资源。内核栈中保存了能够帮助程序恢复运行的信息,例如:返回地址、当前条件码

包括鼠标、键盘的交互,都是通过异常执行的

Linux:异常
Windows:中断

常见异常

同步异常:与程序的执行息息相关

被执行的指令所引起的事件(自己愿意引起的异常)

包括:

陷阱:跟踪时设置的断点,称之为陷阱(程序执行到断点时的停止)。会返回到下一条指令

故障:例如页故障(尝试找到某一页,发现不在内存中,这个故障是可以修复的)、保护故障(访问时发现越界了——只允许在某个内存范围内访问,但却超出了这个范围,导致访问被拒绝)

中断/终止:蓝屏(检查到内存出现问题等)、死机等

每一个异常,都是有对应的编号的。其中,0-31对应了固定的异常,而从32开始则是自定义异常。
  
常见的同步异常:除数为0异常、保护异常、页故障、机器检测问题、其他异常(从32号开始,都是任意定义的,而32号之前的则是固定的)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值