(Этот ответ предназначен для 32-битной x86 Linux, чтобы соответствовать вашему вопросу; для 64-битной x86 и других архитектур все немного по-другому.)
Параметры передаются из пользовательского пространства в регистрах как Love говорит.
Когда пользовательское пространство вызывает системный вызов с int $0x80
, код входа системного вызова ядра получает управление. Это написано на ассемблере, и его можно увидеть, например, здесь . Одно из действий этого кода - это взять параметры из регистров и поместить их в стек, а затем вызвать соответствующую функцию ядра sys_XXX()
(которая записана в C). Таким образом, эти функции действительно ожидают, что их аргументы будут в стеке.
Также не сработает попытка передать параметры из пользовательского пространства ядру в стеке. Когда выполняется системный вызов, ЦП переключается на отдельный стек ядра, поэтому параметры должны быть скопированы из стека пользовательского пространства в стек ядра, а это несколько сложно. И это нужно было бы сделать даже для очень простых системных вызовов, которые принимают всего несколько числовых c аргументов и в противном случае вообще не нуждались бы в доступе к памяти пользовательского пространства (подумайте, например, о close()
).