У меня есть приложение для сборки для Linux x64, где я передаю аргументы функциям через регистры, поэтому я использую определенное определенное соглашение о вызове, в данном случае fastcall. Теперь я хочу вызвать функцию C из приложения сборки, которое, скажем, ожидает 10 аргументов. Должен ли я переключиться на cdecl
для этого и передать аргументы через стек, независимо от того, что во всем остальном в моем приложении я передаю их через регистры? Разрешено ли смешивать вызовы в одном приложении?Вызов функции C из сборки - вызов вызова вызова
ответ
Я полагаю, что азЬсаИ, вы имеете в виду соглашение amd64 вызова, используемую SysV ABI (то есть то, что использует Linux), где первые аргументы передаются в rdi
, rsi
и rdx
.
ABI немного сложный, следующее упрощение. Возможно, вы захотите прочитать the specification.
Вообще говоря, первые несколько (Левые) целое число или указатель аргументы помещаются в регистры rdi
, rsi
, rdx
, rcx
, r8
и r9
. Аргументы с плавающей запятой передаются в xmm0
- xmm7
. Если пространство регистров исчерпано, дополнительные аргументы передаются через стек справа налево. Например, чтобы вызвать функцию с 10 целочисленных аргументов:
foo(a, b, c, d, e, f, g, h, i, k);
вам нужно будет примерно такой код:
mov $a,%edi
mov $b,%esi
mov $c,%edx
mov $d,%ecx
mov $e,%r8d
mov $f,%r9d
push $k
push $i
push $h
push $g
call foo
add $32,%rsp
Для вашего конкретного примера из getnameinfo
:
int getnameinfo(
const struct sockaddr *sa,
socklen_t salen,
char *host,
size_t hostlen,
char *serv,
size_t servlen,
int flags);
Вы бы проход sa
в rdi
, salen
в rsi
, host
в rdx
, hostlen
в rcx
, serv
в r8
, servlen
в r9
и flags
на стеке.
Да, конечно. Соглашение о вызове применяется для каждой функции. Это совершенно применимое приложение:
int __stdcall func1()
{
return(1);
}
int __fastcall func2()
{
return(2);
}
int __cdecl main(void)
{
func1();
func2();
return(0);
}
, если я беру 'getnameinfo' из C, мне нужно передать ** все ** аргументы через стек ему при вызове с Assembly? или мне разрешено передавать часть из них через регистры и часть через стек? или все аргументы через регистры? – Kooiomo
@Kooiomo См. Мой ответ. – fuz
@fuz, это точно не отвечает на мои 3 вопроса. – Kooiomo
Вы можете, но вам не нужно.
__attribute__((fastcall))
только запрашивает первые два параметра, которые должны быть переданы в регистры - все остальное будет автоматически передаваться в стек, как с cdecl
. Это делается для того, чтобы не ограничивать количество параметров, которые могут быть заданы для функции, путем выбора определенного соглашения о вызове.
В вашем примере с 10 параметрами для функции, вызываемой с помощью соглашения о вызове fastcall
, первые два параметра будут передаваться в регистры, остальные 8 - автоматически в стеке, как и при стандартном соглашении о вызове.
Как вы выбрали использовать fastcall
для всех ваших других функций, я не вижу причины, почему вы хотите изменить это для одной конкретной функции.
1) не eax, а rax. 2) почему? существуют регистры r1-r10 для x64 Linux. – Kooiomo
ОП указана x64, 'fastcall' не стандартизирован, и ваш пример - это реализация MS, а не Sys V, которая будет использовать как минимум RDI и RSI в качестве первого и второго аргументов. –
- 1. C вызов функции вызова
- 2. C-вызов вызова вложенной функции
- 3. Вызов указателя функции вызова
- 4. вызов функции вызова python
- 5. Ограниченный вызов функции вызова
- 6. C вызов вызова: бесконечный цикл
- 7. вызов другой функции из функции обратного вызова
- 8. Вызов функции сборки из C
- 9. Вызов функции javascript от вызова?
- 10. Вызов инлайн функции сборки из C
- 11. Пользовательский вызов вызова X86_64 для вызова функции C
- 12. Swift - вызов функции вызова в obj c
- 13. Вызов продолжение против вызова функции
- 14. вызов функции вызова в javascript
- 15. jQuery Autocomplete, вызов функции вызова
- 16. вызов вызова функции jQuery $ .post
- 17. Вызов функции вызова другой также
- 18. Функция вызова вызова вызова или не вызов
- 19. Вызов функции C из сборки, segfault
- 20. вызов Objective C и C из функции обратного вызова Swift
- 21. Вызов функции внутри другого вызова функции
- 22. Функции вызова из сборки x86_64
- 23. x86 Linux вызов вызова вызова?
- 24. Nodejs, вызов функции функции асинхронного вызова
- 25. Обратный вызов вызова из массива
- 26. C вызов вызова оболочки сценарий
- 27. Вызов функции обратного вызова в Delphi из C++ DLL
- 28. Вызов функции обратного вызова приложения .NET из процессоров Код C
- 29. Определить последний вызов функции обратного вызова
- 30. Вызов функции C++ из C#
Вы читали [спецификацию ABI] (http://refspecs.linuxfoundation.org/elf/x86-64-abi-0.99.pdf)? В нем говорится, как работать с функциями, которые принимают больше аргументов, чем доступные регистры. – fuz