大家好,又见面了,我是你们的朋友全栈君。
系统调用和高级编程语言的移植性
操作系统的硬件控制功能,通常是通过一些小的函数集合体的形式来提供的。这些函数及调用函数的行为统称为系统调用(system call),也就是应用对操作系统(system)的功能进行调用(call)的意思。在前面的程序中用到了time()及printf()等函数,这些函数内部也都使用了系统调用。这里之所以用“内部”这个词,是因为在Windows操作系统中,提供返回当前日期和时刻,以及在显示器中显示字符串等功能的系统调用的函数名,并不是time()和printf()。系统调用是在time()和printf()函数的内部执行的。大家可能会认为这个方法有些绕,不过这是有原因的。
C语言等高级编程语言并不依存于特定的操作系统。这是因为人们希望不管是Windows还是Linux,都能使用几乎相同的源代码。因此,高级编程语言的机制就是,使用独自的函数名,然后再在编译时将其转换成相应操作系统的系统调用(也有可能是多个系统调用的组合)。也就是说,用高级编程语言编写的应用在编译后,就转换成了利用系统调用的本地代码(图9-6)。
图9-6 高级编程语言的函数调用在编译后变成了系统调用
在高级编程语言中,也存在可以直接调用系统调用的编程语言。不过,利用这种方式做成的应用,移植性①并不友好(也俗称为有恶意行为的应用)。例如,直接调用Windows系统调用的应用,在Linux上显然是无法运行的。
Ps:①移植性指的是同样的程序在不同操作系统下运行时需要花费的时间等,费时越少说明移植性越好。
Win编译和链接机制
应用和硬件无关?
在用C语言等高级编程语言开发的Windows应用中,大家很少能接触到直接控制硬件的指令。这是因为硬件的控制是由Windows全权负责的。
不过,Windows提供了通过应用来间接控制硬件的方法。利用操作系统提供的系统调用功能就可以实现对硬件的控制。在Windows中,系统调用称为API(图11-1)。各API就是应用调用的函数。这些函数的实体被存储在DLL文件中。
图11-1 应用通过操作系统间接控制硬件
下面让我们来看一个利用系统调用来间接控制硬件的示例。例如,假设要在窗口中显示字符串,就可以使用Windows API中的TextOut函数①。TextOut的语法如代码清单11-1所示。在这段代码中,确实没有能让大家意识到硬件的参数。带有“设备描述表的句柄”这一注释的参数hdc,是用来指定字符串及图形等绘制对象的识别值,表示的也不是直接硬件设备。
代码清单11-1 TextOut函数的语法(C语言)
代码语言:javascript复制BOOL TextOut(
HDC hdc, //设备描述表的句柄
int nXStart, //显示字符串的x坐标
int nYStart, //显示字符串的y坐标
LPCTSTR lpString, //指向字符串的指针
int cbString //字符串的文字数
);
那么,在处理TextOut函数的内容时,Windows做了什么呢?从结果来看,Windows直接控制了作为硬件的显示器。但Windows本身也是软件,由此可见,Windows应该向CPU传递了某些指令,从而通过软件控制了硬件。
Ps:注脚
① 在向窗口和打印机输出字符串时,可以使用Windows提供的TextOut函数作为API。C语言提供的printf函数,是用来在命令提示符中显示字符串的函数。使用printf函数,是无法向窗口和打印机输出字符串的。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/154108.html原文链接:https://javaforall.cn