我们把整个计算机调用结构分为四层:
最上层是应用层。不管是浏览器、游戏,还是我们使用的各种开发工具,如Xcode,VS,汇编器自身等,都属于这一范畴。
第二层是操作系统的运行库。我们在程序里调用系统API,比如文件读写,就是调用了第二层提供的相应服务。这种调用通过操作系统的API完成,它沟通了应用层和操作系统的运行库。这也就是为什么不管是在Mac还是Windows上编程,我们都可以调用printf()或fread()等函数。因为不同的操作系统的运行库提供了不同底层的实现,但对应用层提供的API总是一样的。
第三层是操作系统内核。操作系统的运行库通过系统调用(System Call)调用系统内核提供的函数。比如fread属于API,它在Linux下会调用read()这个系统调用,而在Windows下会调用ReadFile()这个系统调用。应用程序可以直接调用系统调用,但是这样一来,我们需要考虑各个操作系统下系统调用的不同,而且系统调用由于更加底层,实现起来也就更加困难。最关键的是,系统调用是通过中断来完成的,涉及到堆栈的保存与恢复,频繁的系统调用会影响性能。
第四层是硬件层。程序无法直接访问这一层,只有操作系统的内核,通过硬件厂商提供的接口才能访问。 这四层之间的关系如下图所示: