我完成了操作系统研究生课程的作业。我得到了很好的分数,而且只漏掉了一个问题的一个小问题。它询问哪些是特权指令,哪些不是。我的回答全部正确,除了一个:将一个寄存器值添加到另一个寄存器值
我回答它是有特权的,但显然不是!怎么会这样呢?
我认为用户通过使用系统调用与寄存器/内存交互,这在某种意义上从用户模式系统调用变为内核模式例程。因此,非特权用户可以调用将一个寄存器值添加到另一个寄存器值,但最终内核正在完成这项工作并且处于内核特权模式。所以它有特权?用户自己无法做到这一点。我错了吗?为什么?!
I finished homework for a graduate course in operating systems. I got a great score and I only missed one tiny point of a question. It asked which were privileged instructions and which were not. I answered all correctly except one: Adding one register value to another
I answered it was privileged but apparently it's not! How can this be?
I figured the user interacts with registers/memory by using systems calls, which in a sense change from user mode system calls to kernel mode routines. Therefore the adding of one register value to another could be called by a non-privileged user, but in the end the kernel is doing the work and is in kernel, privileged mode. Therefore it's privileged? A user can't do it by themselves. Am I wrong? Why?!
发布评论
评论(1)
我不确定为什么您会认为更改寄存器需要内核干预。一些特殊寄存器可能具有特权(那些控制诸如描述符表或保护级别之类的东西,用户模式代码可以通过这些寄存器绕过系统模式保护),但通用寄存器可以自由更改,而无需内核参与。
当您的代码运行时,绝大多数指令将是这样的:
顺便说一句,我只是想象如果每次我都需要对内核进行系统调用,我的代码运行会有多慢增加一个计数器或调用一个函数:-)
我唯一能想到的是,如果您认为您的执行线程不允许任意更改寄存器,因为这可能会影响其他线程的这些寄存器。但是内核会在切换线程时处理这一点 - 所有寄存器都会被打包到某个地方以供稍后使用,并且下一个线程的寄存器将被加载。
根据您的评论,您似乎认为添加的时间是CPU 保护机制应该介入。事实上,此时它还不能介入,因为它不知道您将使用寄存器做什么。您可能只是将其用作计数器。
但是,如果您确实使用它作为访问内存的地址,并且该内存以某种方式无效(在您的地址空间之外,或交换到磁盘),内核将在此时介入以进行纠正情况(将您的应用程序扔掉,或者引入换出的内存)。
然而,即使这不是特权指令,它只是CPU处理页面错误。
特权指令是您根本不允许执行的操作,例如更改中断描述符表位置寄存器或停用中断。
I'm not sure why you would think that changing a register would require kernel intervention. Some special registers may be privileged (those controlling things like descriptor tables or protection levels, with which user-mode code could bypass system-mode protections) but general purpose registers can be changed freely without a kernel getting involved.
When your code is running, the vast majority of instructions would be things like:
As an aside, I'm just imagining how slow my code would run if it required a system call to the kernel every time I incremented a counter or called a function :-)
The only thing I can think of would be if you thought your execution thread wasn't allowed to change registers arbitrarily since that may affect those registers for other threads. But the kernel would take care of that when switching threads - all your registers would be packed away somewhere for later and the ones for the next thread would be loaded in.
Based on your comments, you seem to think that the time of adding is when the CPU protection mechanism should step in. In fact, it can't at that point because it has no idea what you're going to use the register for. You may just be using it as a counter.
However, if you do use it as an address to access memory, and that memory is invalid somehow (outside of your address space, or swapped to disk), the kernel will step in at that point to rectify the situation (toss your application out on its ear, or bring in the swapped-out memory).
However, even that is not a privileged instruction, it's just the CPU handling page faults.
A privileged instruction is something that you're not allowed to do at all, like change the interrupt descriptor table location registers or deactivate interrupts.