int 0x80
в Linux всегда вызывает 32-битный ABI, независимо от того, из какого режима он вызывается: аргументы в ebx
, ecx
,... и числа системных вызовов из /usr/include/asm/unistd_32.h
. (Или происходит сбой в 64-битных ядрах, скомпилированных без CONFIG_IA32_EMULATION
).
64-битный код должен использовать syscall
с номерами вызовов из /usr/include/asm/unistd_64.h
и аргументами в rdi
, rsi
и т.д. См. Каковы соглашения о вызовах для системных вызовов UNIX & Linux на i386 и x86-64, Если ваш вопрос был помечен как дубликат этого, см. Эту ссылку для получения подробных сведений о том, как выполнять системные вызовы в 32- или 64-разрядном коде. Если вы хотите понять, что именно произошло, продолжайте читать.
(Для примера 32-битного и 64-битного sys_write
см. Использование прерывания 0x80 в 64-битном Linux)
syscall
вызовы syscall
выполняются быстрее, чем системные вызовы int 0x80
, поэтому используйте собственный 64-разрядный syscall
если только вы не пишете машинный код полиглота, который выполняется одинаково при выполнении как 32- или 64-разрядный. (sysenter
всегда возвращается в 32-битном режиме, поэтому он бесполезен из 64-битного пространства пользователя, хотя это действительная инструкция x86-64.)
Связанный: sysenter
системным вызовам Linux (на x86), как делать int 0x80
или 32-разрядные системные вызовы syscall
, или 64-разрядные системные вызовы syscall, или вызывать vDSO для "виртуальных" системных вызовов, таких как gettimeofday
. Плюс справочная информация о том, что системные вызовы все.
Использование int 0x80
позволяет написать что-то, что будет собираться в 32- или 64-битном режиме, так что это удобно для exit_group()
в конце микробенчмарка или чего-то еще.
Текущие PDF файлы официальных документов psABI для i386 и x86-64 System V, которые стандартизируют соглашения о вызовах функций и системных вызовов, приведены по адресу https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI.
Смотрите x86 теги вики для начинающих гидов, х86 руководств, официальной документации, а также оптимизации производительности гидов/ресурсов.
Но поскольку люди продолжают публиковать вопросы с кодом, использующим int 0x80
в 64-битном коде, или случайно собирают 64-битные двоичные файлы из исходного кода, написанного для 32-битных, мне интересно, что именно происходит в нынешнем Linux?
int 0x80
/восстанавливает ли int 0x80
все 64-битные регистры? Обрезает ли он какие-либо регистры до 32-битного? Что произойдет, если вы передадите аргументы-указатели с ненулевыми верхними половинами?
Это работает, если вы передаете это 32-битные указатели?