相关疑难解决方法(0)

系统调用如何工作?

据我所知,用户可以拥有一个进程,每个进程都有一个地址空间(包含有效的内存位置,这个进程可以参考).我知道进程可以调用系统调用并将参数传递给它,就像任何其他库函数一样.这似乎表明所有系统调用都是通过共享内存等进入进程地址空间.但也许,这只是一个错觉,因为在高级编程语言中,系统调用看起来像任何其他函数,当进程叫它.

但是,现在让我更进一步,更深入地分析引擎盖下发生的事情.编译器如何编译系统调用?它可能会将进程提供的系统调用名称和参数压入堆栈,然后将汇编指令说成"TRAP"或其他东西 - 基本上是用于调用软件中断的汇编指令.

该TRAP汇编指令由硬件执行,首先将模式位从用户切换到内核,然后将代码指针设置为说明中断服务程序的开始.从这一点开始,ISR在内核模式下执行,从堆栈中获取参数(这是可能的,因为内核可以访问任何内存位置,甚至是用户进程拥有的内存位置)并执行系统调用end放弃CPU,再次切换模式位,用户进程从停止的位置开始.

我的理解是否正确?

附上我理解的粗略图: 在此输入图像描述

compiler-construction operating-system process interrupt system-calls

41
推荐指数
3
解决办法
2万
查看次数

如何在Linux中实现系统调用?

当我在用户模式下调用系统调用时,如何在OS中处理调用?

它会调用一些可执行的二进制文件还是某些标准库?

如果是,完成通话需要什么样的东西?

linux operating-system

38
推荐指数
3
解决办法
3万
查看次数

是否有一个单独的内核级线程来处理用户进程的系统调用?

据我所知,用户级线程是在用户空间中实现的,而内核级线程是在内核空间中实现的。我还读到用户级线程被映射到内核级线程以实际运行用户级线程。

  1. “实施”到底是什么意思?这是否意味着线程控制块分别定义在用户空间和内核空间中?

  2. 当进行系统调用时会发生什么?该系统调用在哪个内核线程(或用户线程 IDK)上运行?每个内核级堆栈都有自己的堆栈吗?

  3. 我知道线程只是进程的一部分。当我们处理内核线程时,这里对应的进程是什么呢?内核进程是什么,你能举个例子吗?

我也参考了其他答案,但没有得到满意的结果。

multithreading operating-system kernel process system-calls

7
推荐指数
1
解决办法
1129
查看次数

C 调用约定:谁在可变参数函数与普通函数中清理堆栈?

有一些调用约定(例如pascalstdcall),但就我而言,C 确实使用cdecl(C 声明)。这些约定中的每一个在调用者将参数加载到堆栈上的方式上都略有不同,分别是由哪个(调用者/被调用者)进行清理

谈到清理,这是我的问题。我不明白:有三种不同的东西吗?

  1. 堆栈清洁
  2. 将指针移回倒数第二个堆栈帧
  3. 堆栈恢复

或者我应该怎么看他们?

此外,这个问题的目标基本上是可变参数函数如何在像 Pascal 这样的调用约定中工作,或者stdcall被调用者应该在哪里清除/清理/恢复(我不知道哪个操作)堆栈 - 但他不知道有多少参数它会收到。

编辑

为什么将参数压入堆栈的顺序如此重要?您仍然拥有第一个参数(不是来自省略号的稳定参数),它为您提供有关 - 例如 - 变量参数数量的信息。并且还有“监护人”,它可以添加到省略号标点符号中,并且可以用作独立于调用约定的变量部分结束的标记。在这个链接中,如果调用者和被调用者在搞乱它们之前都保存了它们的状态,那么为什么调用者和被调用者都应该恢复这些寄存器的值?不应该只有其中一个(例如调用者)在调用函数之前将它们保存在堆栈中,仅此而已?另外,在同一个链接上

“因此,堆栈指针 ESP 可能会上下移动,但 EBP 寄存器保持固定。这很方便,因为这意味着我们始终可以将第一个参数称为 [EBP + 8],而不管在功能。”

推送的变量和局部变量在内存中是连续的。使用 EBP 推荐他们的优势在哪里?即使堆栈大小发生变化,它们之间也永远不会有一些动态偏移。

我读过的材料之一是这个站点(只是开始),以便更好地了解堆栈帧到底是什么。然后我继续 yt 并找到了这些堆栈概述调用堆栈教程,但他们不知何故错过了我需要的部分。当你调用函数时到底发生了什么(我不明白指令“调用地址”后跟下一个指令a push值到堆栈上,这意味着返回值)。谁来控制退货地址?呼叫者,召集者?被叫方?当被调用者返回时,程序继续执行一条指令,该指令是从寄存器中读取操作或什么?

c x86 cdecl variadic-functions calling-convention

7
推荐指数
1
解决办法
341
查看次数