Посмотрите справочные страницы Linux (раздел 2). http://man7.org/linux/man-pages/dir_section_2.html
Неважно, какой ассемблер (или компилятор C) вы используете для создания машинного кода x86-64, системные вызовы, которые вы можете сделать, одинаковы. (Поместите номер вызова в RAX и выполните инструкцию syscall
; внутри ядра он использует этот номер для индексации таблицы указателей функций. Или возвращает -ENOSYS
, если он выходит за пределы диапазона.)
Отладка вашей программы с помощью strace ./my_program
для отслеживания системных вызовов, которые она делает. Это декодирует аргументы и возвращает значения в значимые вещи для каждого вызова, поэтому вы можете легко увидеть, передали ли вы неверный указатель, делающий системный вызов вернуть -EFAULT
например. (Системные вызовы не вызывают SIGSEGV / segfault, они просто возвращают ошибку.)
/usr/include/asm/unistd_64.h
имеет действительные числа. (Включено <asm/unistd.h>
при компиляции для 64-битной версии). Страницы руководства документируют аргументы с точки зрения синтаксиса C. Учитывая прототип C, вы можете разработать asm ABI в соответствии с x86-64 System V ABI . (То же, что ABI-вызов функции, за исключением того, что для 4-го аргумента вместо RX вместо RCX используется 4). Каковы соглашения о вызовах для системных вызовов UNIX & Linux на i386 и x86-64
syscall(2)
- это glib c функция-обертка для системных вызовов, а справочная страница syscall также документирует ABI для различных Linux платформ ( x86-64, SPAR C, ARM и др. c.), включая регистры для номера вызова и ret val, а также инструкцию для входа в ядро. Обратите внимание, что имя функции, совпадающее с инструкцией x86-64 syscall
, является просто совпадением.
Никто не утруждает себя созданием исчерпывающей документации для каждого системного вызова для каждого отдельного варианта asm синтаксис - вся информация находится на страницах руководства, плюс документ соглашения о вызовах; раздел NOTES Linux справочных страниц документирует различия между API оболочки библиотеки C и базовым системным вызовом asm.
См. также https://blog.packagecloud.io/eng/2016/04/05/the-definitive-guide-to-linux-system-calls/ для более подробной информации о VDSO для эффективной работы getpid
/ clock_gettime
даже без входа в ядро.
Однако некоторые люди составляют таблицы имен системных вызовов и номеров вызовов Linux x86-64 и регистров arg. Я никогда не находил это полезным (соглашение о вызове системного вызова настолько близко к соглашению о вызове функции, что его легко запомнить), но https://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/ есть, если вы этого хотите.
Существуют заметные различия между функцией POSIX и необработанным системным вызовом Linux для пары вызовов: например, brk
/ sbrk
, а также getpriority
, где возвращаемые значения «хороших» уровней смещены, поэтому они не находятся в диапазоне -4095..-1
кодов ошибок. Но большинство системных вызовов имеют ABI, который в точности соответствует прототипу оболочки библиотеки C , и в этом случае в разделе NOTES ничего не упоминается.