Что лучше "int 0x80" или "syscall"?
Я изучаю ядро Linux и выяснил, что для x86_64
архитектура прерывание int 0x80
не работает как вызов для системного вызова.
Вопрос: в случае x86
архитектура что предпочтительнее syscall
или же int 0x80
и почему?
РЕДАКТИРОВАТЬ: я использую ядро 3.4
4 ответа
syscall
способ входа в режим ядра по умолчаниюx86-64
, Эта инструкция недоступна в 32-битных режимах работы на процессорах Intel.sysenter
это инструкция, наиболее часто используемая для вызова системных вызовов в 32-битных режимах работы. Это похоже наsyscall
, немного сложнее в использовании, но это проблема ядра.int 0x80
это устаревший способ вызова системного вызова, и его следует избегать.
Предпочтительным способом вызова системного вызова является использование VDSO, части памяти, отображаемой в адресном пространстве каждого процесса, которая позволяет более эффективно использовать системные вызовы (например, вообще не входя в режим ядра). VDSO также заботится о более сложных, по сравнению с наследием int 0x80
способ обработки syscall
или же sysenter
инструкции.
Мой ответ здесь охватывает ваш вопрос.
На практике в последних ядрах реализована VDSO, в частности, для динамической оптимизации системных вызовов (ядро устанавливает для VDSO некоторый код, наилучший для текущего процессора). Поэтому вы должны использовать VDSO, и вы лучше будете использовать для существующих системных вызовов интерфейс, предоставляемый libc.
Обратите внимание, что, AFAIK, значительная часть стоимости простых системных вызовов переходит от пространства пользователя к ядру и обратно. Следовательно, для некоторых системных вызовов (вероятно, gettimeofday
, getpid
...) VDSO может избежать даже этого (и технически может избежать реального системного вызова). Для большинства системных вызовов (например, open
, read
, send
, mmap
....) стоимость системного вызова ядра достаточно велика, чтобы можно было улучшить переход от пользовательского пространства к пространству ядра (например, используя SYSENTER
или же SYSCALL
машинные инструкции вместо INT
) незначительный
Остерегайтесь этого перед изменением: номера системных вызовов отличаются при выполнении 0x80 или syscall, например, sys_write равен 4 с 0x80 и 1 с syscall.
http://docs.cs.up.ac.za/programming/asm/derick_tut/syscalls.html для 32 бит или 0x80 http://blog.rchapman.org/post/36801038863/linux-system-call-table-for-x86-64 для системного вызова
int 0x80
это лучшая терминология для обозначения системного вызова ядра, чтобы заставить его что-то делать.
Значение и интерпретация являются взаимозаменяемыми, "сделать системный вызов" или "выпустить в течение 80 часов".
Это не отличается от дней DOS:
- вызовите int 21h, чтобы заставить DOS сделать что-то новое для регистра AX и, необязательно, пары регистров ES:DX,
- int 13h - это обработчик жесткого диска BIOS.
- int 10h - экран EGA/VGA.
- int 09h - обработчик клавиатуры.
Общая тема здесь такова: когда вызывается прерывание / системный вызов, ядро проверяет состояние регистров, чтобы увидеть, какой тип системного вызова требуется. Глядя на, например, eax
зарегистрировать, например, и определить, что нужно выполнить, внутренне переключить контекст в пространство ядра, выполнить процедуру и переключить контекст обратно в пользовательское пространство с возможностью возврата обратно результатов вызова, то есть, был ли он успешным или был в неудаче.