2010-01-15 5 views
5

Я должен сделать интерфейс (скажем, обертку), который разрешает вызов из ассемблерного кода X86_64, используя его вызывающее соглашение для функции C, с другим соглашением о вызовах. Лучше всего было бы быть «независимым от компилятора» (juste modifying the wrapper), поэтому я ищу что-то, что добавляет элементы реестров/стека в компилятор. Я уже смотрю здесь: Custom calling convention for P/Invoke and C#, и он близок к тому, что я должен делать. В настоящее время я использую GCC, но подсказки от других компиляторов приветствуются!Пользовательский вызов вызова X86_64 для вызова функции C

Итак, вот это вещь, для лучшего зрения проблемы (Конвенция пользовательского кодирования странно):

pushq %r11 # saves r11 for call 
movq 64bits_address %r11 # move a 64 bits address that points on a data structure 
callq *8(%r11) # calls an address in the data structure 
popq %r11  # restores %r11 ; return value is in the structure 

мне нужно, чтобы быть в состоянии назвать «специальный» (обертка) функции C ; здесь задание будет направлять вызовы между другими функциями C. Поэтому этой оболочке нужно найти% r11, сохранить все регистры и подготовить стек для дальнейшего вызова. Есть ли способ сделать это в C (с некоторым встроенным asm)?

Большое спасибо

+0

Visual C++ имеет модификатор '__declspec (голый)', который мешает компилятору генерировать пролог и эпилог. –

+0

__declspec (голый) не поддерживается при компиляции для целей x64 (и встроенной сборки тоже). – Andrey

ответ

3

Для документации о призвании конвенции и каким образом параметр передается функции (в регистрах? Какие? Что в стеке и т.д.), посмотрите на Agner Fog's document.

Затем вы можете посмотреть исходный код libffi, чтобы узнать, как они это делают.

+0

Спасибо за ответ; Я не знал libffi, я собираюсь проверить это, это здорово. – Matthieu

+0

Если бы я был вами, по возможности, я бы просто полагался на libffi. Он стабилен, поддерживается и обрабатывает многие угловые шкафы –

+0

Хорошо, документ Agner Fog очень полезен. Но libffi не сохраняет все регистры, в частности регистры YMM (еще?). Кстати, я должен быть в состоянии сделать что-то с этим! Большое спасибо. – Matthieu