写在前面:本文将学习《深入理解计算机系统》的第六章 - 关于异常控制流和系统级 I/O 。CSAPP 是计算机科学经典教材《Computer Systems: A Programmer's Perspective》的缩写,该教材由Randal E. Bryant和David R. O'Hallaron 合著。
本篇博客全站热榜排名:未上榜
控制流(Control Flow)指的是程序执行的顺序和流程。程序从一个语句开始执行,然后按照一定的顺序执行其他语句,这些语句之间的执行顺序就构成了程序的控制流。控制流可以分为顺序控制流、选择控制流和循环控制流三种基本类型。
处理器只做一件事:从开机到关机,CPU 只是一次次地读取和执行(解释)一连串的指令。该序列是 CPU 的控制流 (control flow) :
你所知道的:改变流的两种 机制 (mechanisms):
跳转 (Jumps) 和 分支 (branches) ,调用和返回 根据程序状态(即变量的值)执行。
* 跳转指令:在程序中使用跳转指令(如 goto、break、continue)
程序的控制流在计算机中是通过跳转指令(如条件跳转、无条件跳转等)来实现的。在程序运行时,处理器根据指令的执行结果来决定跳转到哪条指令执行,从而实现程序的控制流。
但是,这对于一个有用的系统来说是不够的。
必须要根据 系统状态 (system state) 的变化做出反应。比如:数据从磁盘或网络适配器到达、指令访问了无效的内存地址、用户在键盘上敲 Ctrl-C、系统定时器过期。
OS 需要机制来管理 异常控制流 (exceptional control flow),突然改变控制流程以应对上述情况。
异常处理:在程序运行过程中,如果出现了异常情况(如除零、数组越界等),程序会自动跳转到相应的异常处理代码,进行异常处理并改变程序的控制流。
存在于计算机系统的各个层面。
在计算机系统中,异常控制流(Exception Control Flow)指的是在程序执行过程中发生了异常事件(如除零、内存访问越界、系统调用出错等),导致程序执行流程发生了变化。
底层机制:
上层机制:
Exception:An exception is a transfer of control to the OS kernel in response to some event
什么是异常?异常是对某些事件的控制权转移到操作系统内核的反应。
内核是操作系统的内存驻留部分,比如除零,算术溢出,I/O 请求完成,按 Ctrl-C……
在操作系统中,Exception Tables(异常表)是用于处理中断和异常的一种数据结构。
当操作系统运行过程中发生中断或异常时,操作系统会使用异常表来确定如何处理这些事件。
每种类型的事件都有一个唯一的异常编号 , 是异常表的一个索引。
每次异常 发生时,处理程序 都会被调用。
"Interrupts, Traps, Faults, and Aborts"
异常 (Interrupts)、陷阱 (Traps)、故障 (Faults)、终止 (Aborts)。
由处理器外部的事件引起:通过设置处理器的中断引脚指示,处理程序返回到 "下一个 "指令。
例子:
定时器中断:每隔几毫秒,外置定时器芯片 (external timer chip) 就会触发一次中断、内核用来从用户程序中夺回控制权。
来自外部设备的 I/O 中断:在键盘上按下 Ctrl-C、网络中的数据包到达、磁盘中的数据到达
由执行指令后发生的事件引起的。
陷阱 (Traps):
故障 (Faults):
终止 (Aborts) :
同步异常(陷阱),示例:系统调用 (syscall)
同步异常(陷阱),示例:页错误
同步异常(终止),示例:发生的硬件错误,如奇偶校验错误、当 DRAM 或 SRAM 位损坏时。
* 术语注释,不要沉迷于这种分类法(其实并没有明确的共识!)
示例:选择性显示 (selectively shown):
从 0 到 31 的数字在 Intel 架构中定义(对于任何x86-64系统都是相同的)
从 31 到 255 的数字由操作系统开发人员定义。例如,Linux 为称为系统调用的特殊陷阱 (special trap) 保留 128(0x80)。
每个 x86-64 系统调用都有一个唯一的 ID 号,示例:
用户调用:
open(filename, options)
调用__open函数,该函数调用系统调用指令 syscall。
00000000000e5d70 <__open>:
...
e5d79: b8 02 00 00 00 mov $0x2,%rax # open is syscall #2
e5d7e: 0f 05 syscall # Return value in %rax
e5d80: 48 3d 01 f0 ff ff cmp $0xfffffffffffff001,%rax
...
e5dfa: c3 retq
%rax 包含系统调用号。
其它参数在 %rdi、%rsi、%rdx、%r10、%r8、%r9 中。
以 %rax 为单位的返回值。
负值是与负 errno 相对应的错误
每个 x86-64 系统调用都有一个唯一的 ID 号
例子:
程序访问无效的内存地址。
向用户进程发送 SIGSEGV 信号。
用户进程退出时出现 segmentation fault。
int a[1000];
main ()
{
a[5000] = 13;
}
[ 笔者 ] 王亦优
[ 更新 ] 2023.3.9
❌ [ 勘误 ] /* 暂无 */
[ 声明 ] 由于作者水平有限,本文有错误和不准确之处在所难免,
本人也很想知道这些错误,恳望读者批评指正!
参考资料 Computer Systems: A Programmer's Perspective (3rd Edition) C++reference[EB/OL]. []. http://www.cplusplus.com/reference/. Microsoft. MSDN(Microsoft Developer Network)[EB/OL]. []. . |