Он хранится в стеке ядра.Код записи системного вызова Linux довольно проблематичен, особенно теперь, когда он выполняет некоторые меры по смягчению последствий и распаду, но вы можете посмотреть определение entry_SYSCALL_64
.
В частности, эта последовательность сохраняетСостояние пользовательского потока в стеке ядра.Он строит последнюю часть структуры struct pt_regs
, которую он позже передаст в do_syscall_64
.
/* Construct struct pt_regs on stack */
pushq $__USER_DS /* pt_regs->ss */
pushq PER_CPU_VAR(cpu_tss_rw + TSS_sp2) /* pt_regs->sp */ // This is where it's put on the stack.
pushq %r11 /* pt_regs->flags */
pushq $__USER_CS /* pt_regs->cs */
pushq %rcx /* pt_regs->ip */
GLOBAL(entry_SYSCALL_64_after_hwframe)
pushq %rax /* pt_regs->orig_ax */
PUSH_AND_CLEAR_REGS rax=$-ENOSYS
Что касается регистра ss, то до того, как в x86 была виртуальная память, была этаИдея сегментов.Каждая программа будет жить в своей серии сегментов памяти.Каждый регистр сегмента (ss, gs и т. Д.) Содержал индекс в Глобальной таблице дескрипторов, который определял, с чего начался сегмент и какие у него были разрешения.Сс держал сегмент для стека.Если вы попытаетесь выдвинуть, выдвинуть или вызвать, если esp указывает вне сегмента стека, вы получите исключение сегментации.В наши дни с x86_64 ss и большинством других регистров сегментации в основном рудиментарные, за исключением fs и gs, которые используются для доступа к локальным данным потока в пользовательском пространстве и пространстве ядра соответственно.