When is esp register set on linux?
Background
x86 CPUs have two (actually four) stacks (for each task): one for user mode and one for kernel mode.
When an interrupt occurs in user mode, the CPU will set esp
to the kernel stack address (see "TSS" for more information) and push the original value esp
(user mode stack location) to the stack (kernel). eip
, cs
and are eflags
always pushed onto the stack when an interrupt occurs.
When returning from an interrupt, the command iret
will call the "old" register values ββfrom the stack (kernel), and the stack pointer will point back to the user's stack.
A proactive multitasking operating system typically works like this:
Some task is in progress, which means that this task takes 100% of the CPU usage for a very short amount of time. When a timer interrupt occurs, the register values ββfor the current task are stored on the stack (CPU). The OS will be the push
values ββof all other registers and change the value esp
to the kernel stack of another task (which were saved when another timer interrupt occurred). Then it pops
registers and executes iret
, so all registers contain the values ββof another task, and the other task is executed.
On Linux (4.12.2), x86-32, this is done by a function __switch_to_asm
in the build source "entry_32.S".
Direct answer to your question
When creating a new task, two stacks (user and kernel) are allocated for this task, and the initial values ββof the registers poped
in the interrupt are written to the kernel stack. This includes the initial value esp
for user mode.
Some timer interrupt later the task is started for the first time (just like the started task is activated again).
In (older versions) Linux, two commands are used to create a new task:
-
fork()
will just copy the kernel stack.fork()
will duplicate the existing task, so all register values ββ(includingesp
) must be identical to the already existing task -
execve()
will not allocate a new kernel stack (a new task is now created, but another executable is running in the current task). Execve will allocate a new user stack and overwrite the valueesp
on the kernel stack. (Mark Carpenter's commentary shows you where this is done.)
source to share