0

As I understood before, each process has its own address space called vitual address space or program memory, and every process has a location called stack which is used to store local variables and parameters of a function.

Also, when an exception occurs the processor (say an ARM cortex-A) switches to privileged mode and then branches to the exception handler.

According to what I understood, most applications run in non-privileged user mode, and this mode has a special register called stack pointer to hold the address of top of the stack; but this is a single register and can't actually hold the address of top of the stack of several processes at the same time. Would you please explain what actually happens?

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299

1 Answers1

0

As for all registers, it's saved and put away in a data structure associated to the process once the OS decides it's time for another process to run ("context switch"); it's as if it took a snapshot of the current processor state.

When the process is scheduled again, all registers are restored (including the instruction pointer) and execution resumes as if nothing happened.

According to what I understood, most applications run in non-privileged user mode, and this mode has a special register called stack pointer to hold the address of top of the stack

The stack pointer is not specific of user mode, the processor always has (and can use) it, regardless of the mode.

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
  • So where exactly that taken snapshot is kept in process's memory layout? – Babak Akbari Oct 27 '17 at 08:00
  • It depends from the operating system; generally every multitasking OS has some "schedulable entity" kernel-side structure, where such data is stored (along with other task-related data). – Matteo Italia Oct 27 '17 at 09:14
  • Now, looking at the exact implementation in Linux it's a bit more complicated - part is saved in the task structure, part is saved on the stack of the paused task. – Matteo Italia Oct 27 '17 at 09:43
  • 2
    In Linux, each task has a supervisor stack. This stack contains a 'thread_info' and user registers (including stack pointer). The super stack is 8K (or two mmu pages). All Linux faults (interrupts, memory, alignment, etc) all switch to this supervisor stack. When the kernel task switches, the 'super sp' is swapped and then the MMU view of things. There is a list (probably several and maybe trees) of all tasks to these 8k pages. The 'thread_info' has a pointer to complete process info. Also the super stack maintains call info to/between kernel functions (just like user space). – artless noise Oct 31 '17 at 22:05
  • 1
    Maybe helpful, [ARM kernel exception stack](https://stackoverflow.com/questions/22928904/linux-kernel-arm-exception-stack-init), [ARM TLS](https://stackoverflow.com/questions/29818269/code-sequences-for-tls-on-arm), [ARM interrupts and context saving](https://stackoverflow.com/questions/32865407/arm-interrupts-and-context-saving), etc. The ARM Linux kernel is not unique. Most OSs will use variations on this, but with twists that may effect performance, memory foot print and features. – artless noise Oct 31 '17 at 22:09