2
\$\begingroup\$

A fundamental component of any OS is multi-tasking. It must be able to switch between tasks/processes.

What registers are required to be saved and restored when performing a context switch? Where are their values saved to?

\$\endgroup\$
  • 1
    \$\begingroup\$ Any registers that aren't "temporary" or "kernel" - i.e., ones that are expected to remain the same between instructions of a user application. They are stored on the stack of the process. Without knowing which CPU we can't be more exact. \$\endgroup\$ – Majenko Jun 13 '14 at 18:01
  • \$\begingroup\$ What type OS? RTOSs or etc - Which? - Define "context switch" \$\endgroup\$ – Roh Jun 13 '14 at 18:09
  • \$\begingroup\$ OK, lets say a RTOS and we are talking about a PIC and lets say.. an x86 processor. How do I find out how context switch is done on these? I did not know that the answer can depend on OS. \$\endgroup\$ – quantum231 Jun 13 '14 at 18:11
  • \$\begingroup\$ @Majenko They're stored in the kernel. If they were stored in the stack of the process, they would be unrecoverable, as one of them is the stack pointer. \$\endgroup\$ – user207421 Jun 13 '14 at 18:50
  • 4
    \$\begingroup\$ @EJP: Actually, in most operating systems, they are mostly stored on the stack, since that's where an interrupt typically puts them anyway. Only the stack pointer itself is stored in a kernel table, and serves as a "handle" to that particular context. \$\endgroup\$ – Dave Tweed Jun 13 '14 at 18:53
9
\$\begingroup\$

Firstly, if the OS is not pre-emptively multitasking, then it only has to save those registers which are not saved by the usual procedure call conventions. In a non-preemptively multi-tasking kernel, task switches only take place in explicit calls to the kernel. The kernel has to save only the "procedure context", and not the full, detailed machine context, so that when the task is re-started, the task can execute a successful return from the function which it called. This means saving and restoring just those registers that a function is normally expected to preserve.

In a pre-emptive kernel, you have to save a much more detailed machine state, since an interrupt can come in at any time and pre-empt a task.

However, it is still up to you to decide what registers you care about. If there are certain registers that none of your tasks use, then you don't have to bother saving and restoring them.

For instance, suppose there are some special floating-point registers, but your system doesn't use them. Then you don't have to bother.

If someone happens to need to do floating-point, then if they are the only task doing that, the registers will be left alone by everything else (other tasks and interrupts). If someone introduces multiple tasks, some hack can be put in place, like using some well-known mutex around floating-point code (or simply disabling interrupts, if there is just one processor).

The "canonical answer" is to save all aspects of processor state which pertain to a task. Any register or other processor state which is not saved and restored will, in a given task, appear to spontaneously change value. If that is "bad", it has to be prevented. Not all registers are "aspects of processor state which pertain to a task". For instance on MIPS, there are "kernel registers" called k0 and k1. The architecture spec says that trap handlers are allowed to use these registers for whatever purpose they want and not restore them. So, from the point of view of any normal code, k0 and k1 have values which change spontaneously as various interrupts go off, and the handlers clobber those registers.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.