... утверждение, что внешняя функция является «неопределенной ссылкой»
LOL!Линкеры не "утверждают" ложь.Вы не будете убеждать , что он передумает, настаивая на том, что вы правы или нет.Примите то, что инструменты говорят вам, чтобы быть правдой без промедления.Это ключ к быстрой идентификации проблемы.
Почти каждый компилятор C, включая те, которые вы используете, генерирует глобальные символы с префиксом подчеркивания, чтобы минимизировать конфликты имен с символами на ассемблере.Например, измените свой код на
extern _printf
...
call _printf
, и сообщения об ошибках о том, что printf
не определен, исчезнут.Если вы do получаете неопределенную ссылку на _printf
, это потому, что компоновщик не обращается к библиотеке времени выполнения C.Команда link может быть сложной, чтобы получить правильную.Обычно это не очень познавательно, так что читайте с рабочего проекта или ищите пример.Именно поэтому IDE очень полезны.
Что касается кода C, вызывающего функцию сборки, обычно проще всего написать функцию сборки с использованием соглашений C:
global _do_str
_do_str:
В качестве альтернативы, вы можетеможет объявить функцию для использования соглашения о вызовах Pascal:
extern int pascal do_str ( whatever parameters are needed);
...
retval = do_str ("hello world");
Соглашение о вызовах Pascal существенно отличается от C: оно не добавляет перед символом начальное подчеркивание, вызывающий отвечает за удаление параметров послеreturn, и параметры находятся в другом порядке, возможно, с некоторыми типами данных параметров, передаваемыми в регистрах, а не в стеке.См. Ссылки компилятора для всех деталей.