Предполагая соглашение о вызовах при комбинировании сборки C и x86 - PullRequest
4 голосов
/ 19 февраля 2012

У меня есть некоторые процедуры сборки, которые вызываются и принимают аргументы из функций C.Прямо сейчас я предполагаю, что эти аргументы передаются в стек в порядке cdecl.Это справедливое предположение?

Будет ли компилятор (GCC) обнаруживать это и проверять правильность передачи аргументов, или я должен вручную пойти и объявить их cdecl?Если да, будет ли этот атрибут сохраняться, если я укажу более высокий уровень оптимизации?

Ответы [ 3 ]

2 голосов
/ 19 февраля 2012

Соглашения о вызовах означают гораздо больше, чем просто порядок аргументов. Есть хороший PDF-файл, объясняющий все детали, написанные Агнером Фогом: Соглашения о вызовах для различных компиляторов C ++ и операционных систем .

1 голос
/ 19 февраля 2012

Это вопрос ABI для платформы, для которой вы пишете код. Почти все платформы следуют соглашению о вызовах Unix System V ABI для C и другим проблемам ABI, которые включают как общий документ ABI (gABI), подробно описывающий общие характеристики ABI для всех архитектур ЦП, так и документ ABI (psABI) для конкретного процессора, относящийся к конкретная архитектура процессора / семейство. Когда дело доходит до x86, это соответствует тому, что вы называете "cdecl". Таким образом, с практической точки зрения сборка x86, предназначенная для вызова из C, должна быть написана так, чтобы предполагать «cdecl». По сути, единственное исключение из универсальности этого соглашения о вызовах - это функции Windows API, которые используют свое собственное нестандартное соглашение о вызовах «stdcall» из-за унаследованных проблем совместимости Win16 dll thunk; тем не менее, соглашение о вызовах «по умолчанию» в Windows x86 по-прежнему «cdecl».

Более важной проблемой при написании asm для вызова из C является то, должны ли имена символов начинаться с подчеркивания или нет. Это сильно варьируется в зависимости от платформы, при этом общая тенденция заключается в том, что платформы на основе ELF не используют префикс, а большинство других платформ используют ...

0 голосов
/ 19 февраля 2012

Быстрый и грязный способ сделать это - создать фиктивную функцию C, которая соответствует функции asm, которую вы хотите реализовать, сделать несколько вещей в фиктивной функции C с переданными параметрами, чтобы вы могли различить их, затем скомпилировать разобрать. Не надежно, но работает часто.

...