С точки зрения программиста приложения системный вызов - это просто вызов процедуры из библиотеки-оболочки. Поскольку я не очень хорошо разбираюсь в сборке, мне было интересно, как это делается на самом низком уровне. Как еще приложение может вызывать системный вызов без использования библиотеки?
1 ответ
Системные вызовы зависят от архитектуры, но все они имеют сходные черты.
В x86 системные вызовы выполняются либо через программные прерывания, либо через специальную инструкцию "systenter". Linux может использовать любой из них, но программное прерывание является наиболее распространенным. Во время загрузки ядро устанавливает обработчики прерываний, как прерываний, генерируемых аппаратным, так и программных. В x86 есть специальная инструкция по сборке int, которая генерирует программное прерывание. Ядро установило обработчик для программного прерывания 0x80, чтобы оно было системным вызовом.
В этой таблице показаны все возможные системные вызовы и их параметры, а также способы их передачи. Как видите, номер в регистре eax указывает, какой системный вызов. Другие регистры указывают на какой-либо параметр системного вызова.
Таким образом, программное обеспечение пользователя просто устанавливает правильные параметры в регистрах, а затем выдает прерывание 0x80. В ядре настроен обработчик для интерпретации системного вызова, выполнения функции и возврата, изменив регистры с любым возможным возвращаемым значением.
Хотя функции-оболочки делают все это и, как правило, переносимо, нет никаких причин, по которым вы не могли бы написать какую-либо встроенную сборку в любом коде C/C++ для непосредственного системного вызова. Вам понадобятся только базовые знания по сборке: переместите правильные данные в правильные регистры, а затем введите 'int 0x80'