Каковы соглашения о вызовах для системных вызовов UNIX & Linux на i386 и x86-64

Следующие ссылки объясняют x86-32 конвенции системного вызова для обоих UNIX (разновидность BSD) и Linux:

Но каковы x86-64 конвенции системного вызова по обеим UNIX & Linux?

132
задан Peter Cordes 3 October 2017 в 03:03
поделиться

2 ответа

Дополнительные материалы для чтения по любой из тем здесь: Полное руководство по системным вызовам Linux


Я проверил их с помощью GNU Assembler (gas) на Linux.

Интерфейс ядра

x86-32, также известное как i386 Соглашение о системном вызове Linux:

В x86-32 параметры системного вызова Linux передаются с использованием регистров. % eax для syscall_number. % ebx,% ecx,% edx,% esi,% edi,% ebp используются для передачи 6 параметров системным вызовам.

Возвращаемое значение находится в % eax . Все остальные регистры (включая EFLAGS) сохраняются в int $ 0x80 .

Я взял следующий фрагмент из Руководства по сборке Linux , но я сомневаюсь в этом. Если бы кто-нибудь мог показать пример, было бы здорово.

Если имеется более шести аргументов, % ebx должен содержать место в памяти , где хранится список аргументов , но не Не беспокойтесь об этом , потому что маловероятно, что вы будете использовать системный вызов с более чем шестью аргументами .

Для примера и дополнительной информации обратитесь к http://www.int80h.org/bsdasm/#alternate-calling-convention . Другой пример Hello World для i386 Linux с использованием int 0x80 : Какие части этого ассемблерного кода HelloWorld необходимы, если я буду писать программу на ассемблере?

Есть более быстрый способ сделать 32-битные системные вызовы: используя sysenter . Ядро отображает страницу памяти в каждый процесс (vDSO) со стороной пользовательского пространства sysenter dance, которая должна взаимодействовать с ядром, чтобы оно могло найти адрес возврата. Сопоставление аргументов с регистрами такое же, как для int $ 0x80 . Обычно следует вызывать vDSO вместо прямого использования sysenter . (См. Полное руководство по системным вызовам Linux для получения информации о связывании и вызове vDSO, а также для получения дополнительной информации о sysenter и обо всем остальном, что связано с системными вызовами.)

x86-32 [Free | Open | Net | DragonFly] Соглашение о системных вызовах BSD UNIX:

Параметры передаются в стек. Поместите параметры (последний параметр помещается первым) в стек.Затем вставьте дополнительные 32-битные фиктивные данные (на самом деле это не фиктивные данные. Для получения дополнительной информации см. Следующую ссылку), а затем дайте команду системного вызова int $ 0x80

http://www.int80h.org / bsdasm / # соглашение о вызовах по умолчанию


Соглашение о системных вызовах x86-64 Linux:

x86-64 Mac OS X похожа, но отличается . TODO: проверьте, что делает * BSD.

См. Раздел: «A.2 AMD64 Linux Соглашения о ядре» в Приложение System V для двоичного интерфейса приложения к процессору архитектуры AMD64 . Последние версии psABI для i386 и x86-64 System V можно найти по ссылке на этой странице в репозитории разработчика ABI . (См. Также вики-страницу с тегами для получения обновленных ссылок на ABI и многих других полезных сведений о x86 asm.)

Вот фрагмент из этого раздела:

  1. Приложения уровня пользователя использовать в качестве целочисленных регистров для передачи последовательности% rdi,% rsi,% rdx,% rcx, % r8 и% r9. Интерфейс ядра использует% rdi,% rsi,% rdx,% r10,% r8 и% r9.
  2. Системный вызов выполняется с помощью инструкции syscall . Этот блокирует% rcx и% r11 , а также возвращаемое значение% rax, но другие регистры сохраняются.
  3. Номер системного вызова должен быть передан в регистр% rax.
  4. Системные вызовы ограничены шестью аргументами, аргумент не передается непосредственно в стек.
  5. При возврате из системного вызова регистр% rax содержит результат системного вызова. Значение в диапазоне от -4095 до -1 указывает на ошибку, это -errno .
  6. Ядру передаются только значения класса INTEGER или класса MEMORY.

Помните, что это из специального приложения к ABI для Linux, и даже для Linux оно информативно, а не нормативно. (Но на самом деле это так.)

Это 32-bit int $ 0x80 ABI можно использовать в 64-битном коде (но настоятельно не рекомендуется). Что произойдет, если вы используете 32-битный int 0x80 Linux ABI в 64-битном коде? Он по-прежнему усекает свои входные данные до 32-битного, поэтому он не подходит для указателей и обнуляет r8-r11.

Пользовательский интерфейс: вызов функции

Соглашение о вызове функций x86-32:

В x86-32 параметры передавались в стек. Последний параметр был помещен в стек первым до тех пор, пока не будут выполнены все параметры, а затем была выполнена инструкция call . Это используется для вызова функций библиотеки C (libc) в Linux из сборки.

Современные версии i386 System V ABI (используемые в Linux) требуют 16-байтового выравнивания % esp перед вызовом , как всегда x86-64 System V ABI требуется. Вызываемым лицам разрешается предполагать это и использовать 16-байтовые SSE для загрузки / сохранения этой ошибки на невыровненных. Но исторически Linux требовала только 4-байтового выравнивания стека, поэтому требовалась дополнительная работа, чтобы зарезервировать естественно выровненное пространство даже для 8-байтового двойного или чего-то подобного.

Некоторые другие современные 32-битные системы по-прежнему не требуют выравнивания стека более чем на 4 байта.


Соглашение о вызове функций пользовательского пространства x86-64 System V:

x86-64 System V передает аргументы в регистры, что более эффективно, чем соглашение об аргументах стека в i386 System V. Это позволяет избежать задержки и дополнительных инструкций по сохранению аргументов в памяти (кеш) и последующей их загрузке обратно в вызываемый объект.Это хорошо работает, потому что доступно больше регистров, и лучше для современных высокопроизводительных процессоров, где важны задержка и неупорядоченное выполнение. (ABI i386 очень старый).

В этом новом механизме: Сначала параметры делятся на классы. Класс каждого параметра определяет способ, которым он передается вызываемой функции.

Для получения полной информации обратитесь к: «3.2 Последовательность вызова функций» Приложение System V Application Binary Interface к процессору архитектуры AMD64 , которое частично гласит:

После классификации аргументов регистрам присваиваются ( в порядке слева направо) для передачи следующим образом:

  1. Если класс - MEMORY, передать аргумент в стеке.
  2. Если класс - INTEGER, используется следующий доступный регистр последовательности % rdi,% rsi,% rdx,% rcx,% r8 и% r9

Итак % rdi, % rsi,% rdx,% rcx,% r8 и% r9 - это регистры в порядке , используемые для передачи целочисленных параметров / указателей (т.е. класса INTEGER) в любую функцию libc из сборки. % rdi используется для первого параметра INTEGER. % rsi для 2-го,% rdx для 3-го и так далее. Затем должна быть дана инструкция call . Стек (% rsp ) должен быть выровнен по 16B при выполнении вызова .

Если имеется более 6 параметров INTEGER, седьмой параметр INTEGER и более поздние передаются в стек. (Вызывающий всплывает, то же самое, что и x86-32.)

Первые 8 аргументов с плавающей запятой передаются в% xmm0-7, позже в стеке. Нет векторных регистров с сохранением вызовов.(Функция с комбинацией аргументов FP и целочисленных аргументов может иметь более 8 общих аргументов регистра.)

Функции с переменным числом аргументов ( например printf ) всегда требуют % al = количество аргументов регистра FP.

Существуют правила упаковки структур в регистры ( rdx: rax при возврате) или в память. См. Подробности в ABI и проверьте вывод компилятора, чтобы убедиться, что ваш код согласуется с компиляторами о том, как что-то должно передаваться / возвращаться.


Обратите внимание, что соглашение о вызове функций Windows x64 имеет несколько существенных отличий от x86-64 System V, например, теневое пространство, которое должно быть зарезервировано вызывающей стороной (вместо красного - зона), и вызовы с сохранением xmm6-xmm15. И очень разные правила, для которых arg входит в какой регистр.

207
ответ дан 24 November 2019 в 00:10
поделиться

Возможно, вам нужен x86_64 ABI?

Если это не совсем то, что вам нужно, используйте 'x86_64 abi' в предпочитаемой вами поисковой системе, чтобы найти альтернативные ссылки.

15
ответ дан 24 November 2019 в 00:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: