Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Operating system 了解对systemcalls的更高级别调用_Operating System_System Calls - Fatal编程技术网

Operating system 了解对systemcalls的更高级别调用

Operating system 了解对systemcalls的更高级别调用,operating-system,system-calls,Operating System,System Calls,我正在看加尔文写的关于OS的书。在第2章的末尾有一节,作者写了关于“向内核添加系统调用”的内容 他描述了如何使用ASMLINK创建一个包含函数的文件,并使其符合系统调用的条件。但在关于如何调用系统调用的下一部分中,他写道: “不幸的是,这些是低级操作,不能使用C语言语句执行,而需要汇编指令。幸运的是,Linux提供了宏来实例化包含适当汇编指令的包装函数。例如,下面的C程序使用_syscallO()调用新定义的系统调用的宏: 基本上,我想了解syscall()函数通常是如何工作的。现在,我对宏的理

我正在看加尔文写的关于OS的书。在第2章的末尾有一节,作者写了关于“向内核添加系统调用”的内容

他描述了如何使用ASMLINK创建一个包含函数的文件,并使其符合系统调用的条件。但在关于如何调用系统调用的下一部分中,他写道:

“不幸的是,这些是低级操作,不能使用C语言语句执行,而需要汇编指令。幸运的是,Linux提供了宏来实例化包含适当汇编指令的包装函数。例如,下面的C程序使用_syscallO()调用新定义的系统调用的宏:

基本上,我想了解syscall()函数通常是如何工作的。现在,我对宏的理解是一个文本替换系统。 (如果我错了,请纠正我) 宏如何调用汇编语言指令? 在编译时,syscallO()是否会被转换为指令的地址(操作码)以执行陷阱?(但这与我的宏概念或定义不符) 里面包含的包装函数是什么,它们也是用汇编语言编写的


假设,我想创建一个我自己的函数来执行系统调用,那么我需要做什么呢?我需要编译它来生成执行陷阱指令的机器代码吗?

伙计,你必须为此支付156美元,然后你实际上必须读它。你可能会得到一个VMS内部代码数据结构书的价格不到30美元

也就是说,让我试着把这些胡言乱语翻译成英语

系统调用不使用其他函数使用的相同类型的链接(即传递参数和调用函数的方法)

为了执行系统服务,您没有执行某种类型的调用指令,而是触发了一个异常(在Intel中被奇怪地称为中断)

CPU期望操作系统创建一个调度表,并将其位置和大小存储在一个特殊的硬件寄存器中。调度表是指向异常和中断处理程序的指针数组

异常和中断都有编号,因此,当异常或中断编号#1出现时,CPU在内核模式下调用调度表中的2d异常处理程序(不是#0,而是#1)

里面包含的包装函数是什么,它们也是用汇编语言编写的

操作系统通常对系统服务使用一个(但有时更多)异常。您需要在汇编语言中执行类似的操作来调用系统服务:

INT $80 ; Explicitly trigger exception 80h 
因为你必须执行一条特定的指令,所以这必须是一条汇编语言指令。也许你的C编译器可以用汇编语言来调用系统服务。但即使可以,每次你想调用系统服务时都必须这样做也是一件非常困难的事

另外,我还没有在这里填写所有细节(仅填写对系统服务的实际调用)。通常,当您在C(或其他)中调用函数时,参数会被推送到程序堆栈上。因为堆栈通常在您进入内核模式时会发生变化,所以系统调用的参数需要存储在寄存器中

此外,您还需要确定要执行的系统服务。通常,系统服务都有编号。系统服务的编号会加载到第一个寄存器中(例如R0或AX)

需要调用系统服务时的完整过程是:

  • 在堆栈上保存要覆盖的寄存器
  • 将要传递给系统服务的参数加载到硬件寄存器中
  • 将系统服务的编号加载到最低的寄存器中
  • 触发异常以进入内核模式
  • 从寄存器卸载系统服务返回的参数
  • 可能做一些错误检查
  • 还原以前保存的寄存器
  • 与每次调用系统服务时都这样做不同,操作系统提供了供高级语言使用的包装器函数。您可以像通常调用函数一样调用包装器。包装器(汇编语言)为您执行上述步骤

    由于这些包装器几乎相同(通常唯一的区别是参数数量不同),因此可以使用宏创建包装器。一些汇编程序具有强大的宏功能,允许单个宏定义所有包装器,即使参数数量不同

    Linux提供了多个_syscallC宏来创建包装器。每个参数都有一个。请注意,这些宏仅适用于操作系统开发人员。包装器存在后,每个人都可以使用它

    宏如何调用汇编语言指令

    这些系统调用宏必须生成内嵌汇编代码


    最后,请注意,这些包装没有定义实际的系统服务。这必须在调度表和系统服务异常处理程序中设置。

    3344003:前两个问题。”CPU希望操作系统创建调度表。“。这难道不意味着CPU的设计是在期望操作系统监督其上的进程的情况下完成的吗?这个调度表总是在运行时创建的吗?@3344003:对VMS内部程序有什么建议吗?一个月后,bios在引导时创建一个调度表。然后,操作系统构建一个新的操作系统,并替换bios中的操作系统。桌子是静止的。一旦操作系统启动,它就不会改变。@user3334003:您能解释一下“内联”汇编代码的确切含义,以及“C编译器可以内联使用汇编语言调用fo”这句话的含义吗