【问题标题】:does the mode bit change when initialising a variable?初始化变量时模式位会改变吗?
【发布时间】:2015-04-23 18:06:24
【问题描述】:

所以我知道系统调用(例如open, close, read, write 等)会两次更改模式位 - 从用户模式到内核模式以服务系统调用请求,然后在完成后返回用户模式。

但是如果我们有例子

int a = open("lol.txt", O_RDONLY);

模式位将再次更改两次以服务于open 系统调用,但是将其分配给变量时呢?假设它需要将变量存储到内存中,我们是否必须返回内核再次处理该请求?即上述行中的模式位是否更改了 2 次或 4 次?

【问题讨论】:

  • @xmojmr 如果你阅读了这个问题,你会发现它不是。
  • 我相信答案就在ABI 中,如果您使用编译器的选项来生成汇编源文件输出就会变得很清楚。答案是,原因是系统调用通过寄存器和直接内存写入将它必须做的一切返回到用户模式。使用变量(本地、全局、易失性等)进行改组完全超出了系统调用的范围。 ABI 指定将用作输入/输出通道的内容,并且局部变量不在列表中
  • @xmojmr 我知道它超出了系统调用的范围,但变量存储在内存中的某个地方——为此,我们必须切换到内核模式,或者至少这是我的假设。所以这就是我的问题 - 一旦我们打开文件并尝试将其保存到某个变量中,我们是否需要回到内核模式?
  • 您的示例中的文件句柄是int。它在一个寄存器中从内核返回。然后可以使用普通的“int b = aC 指令将这个简单的值保存在您想要的任何位置。这是单一的MOV 汇编指令。不需要内核模式来执行这类事情。您能否提供一个更复杂(或更实际)的示例,说明您认为切换到内核并返回可能存在问题的地方?

标签: operating-system kernel system-calls


【解决方案1】:

冒着过于简单化的风险,进入内核模式的唯一方法是通过异常(陷阱或故障)或中断。

对于系统调用,应用程序需要触发一个陷阱。系统调用总是有一个包装函数,它可能进行一些验证,将参数加载到适当的寄存器中(可能从中设置一个堆栈)。然后它执行一条导致陷阱的指令

     TRAP   #100 ; call the 100th exception handler

之后,处理器进入内核模式。将验证参数然后执行内核服务。完成后,它将使用沿以下行的插入返回:

   REI ; return from exception or interrupt

处理器返回用户模式。

open() 可能是也可能不是实际的系统服务。也就是说,我刚刚描述的包装器之一。这取决于系统。 open() 可能是调用多个系统服务的库函数,在这种情况下,处理器将多次进入内核模式并返回。

如果 open() 是系统服务,您可能会进入内核模式并返回一次。

open 函数,无论是否是系统服务,都会返回寄存器中的值。存储值是一个简单的移动指令。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-28
    • 2021-06-07
    • 1970-01-01
    • 2020-10-14
    • 2019-05-17
    • 2021-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多