Asmlinkage означает стек или регистр? - PullRequest
0 голосов
/ 06 мая 2020

В большинстве языков C включен, стек используется для вызовов функций. Вот почему вы получите ошибку «Переполнение стека», если вы не будете осторожны в рекурсии. (Pun не предназначен).

Если это правда, то что такого особенного в директиве asmlinkage G CC.

В ней говорится: # kernelnewbies

Тег asmlinkage - это еще одна вещь, на которую мы должны обратить внимание при использовании этой простой функции. Это #define для некоторого g cc magi c, который сообщает компилятору, что функция не должна ожидать найти какие-либо свои аргументы в регистрах (обычная оптимизация), а только в стеке ЦП.

То есть, я не думаю, что регистры используются в обычных вызовах функций .

Что еще более странно, когда вы узнаете, что реализовано с использованием G CC атрибут функции regparm на x86.

Документация для regparm выглядит следующим образом:

На целевых устройствах x86-32 regparm заставляет компилятор передавать аргументы номер один в число, если они имеют целочисленный тип в регистрах EAX, EDX и ECX, а не в стеке.

пытаюсь сделать.

Так что же происходит? Находятся ли они в стеке или в регистрах.

Где я ошибаюсь?

Информация не очень ясна.

1 Ответ

6 голосов
/ 06 мая 2020

Обычно, чтобы выполнять вызовы быстрее (в зависимости от архитектуры), компилятор может выбрать передачу некоторых параметров через регистры, чтобы каждый раз не копировать их в / из стека. Это особенно верно для частных функций, которые не экспортируются и, следовательно, не обязаны подчиняться соглашениям о вызовах, определенным ABI, для дальнейшей оптимизации.

Некоторые ABI фактически требуют параметров для передаваться в регистры. Соглашение о вызовах System V AMD64 ABI (по умолчанию Linux x86-64) является отличным примером этого: оно требует, чтобы параметры функции передавались через RDI, RSI, RDX, RCX, R8, R9, [XYZ] MM0– 7, поэтому стек используется очень редко.

Теперь при выполнении системного вызова в Linux ядро ​​копирует регистры пользовательского пространства в стек, чтобы сохранить их, а затем вызывает соответствующую функцию системного вызова. Эти функции должны принимать параметры непосредственно из уже сохраненных пользовательских регистров в стеке и поэтому должны быть скомпилированы только и всегда принимать параметры из стека.

In x86 32bit, asmlinkage макрос расширяется до __attribute__((regparam(0))), что в основном сообщает G CC, что никакие параметры не должны передаваться через регистры (0 является важной частью ). На 64-битной x86 он заменяется на более конкретный c __attribute__((syscall_linkage)). Конечный результат тот же: функция вынуждена брать параметры из стека. На других архитектурах, которые всегда передают параметры в стек, никакого специального __attribute__ даже не требуется.

...