Вызов функции стандартной библиотеки C из asm в Visual Studio

У меня возникла проблема с вызовом функции C из проекта asm, созданного в visual studio (Win10 x64, Visual Studio 2015). Проект состоит из одного файла asm:

.586 .model flat, stdcall option casemap:none includelib msvcrt.lib ExitProcess PROTO return:DWORD extern printf:near .data text BYTE "Text", 0 .code main PROC push offset text call printf add esp,4 invoke ExitProcess,0 main ENDP end main 

Когда я создаю проект, компоновщик выводит ошибку:

Ошибка LNK2019 неразрешенный внешний символ _printf, на который ссылается функция _main @ 0

Выходные параметры компоновщика:

/OUT:”C:\Users\apple\Documents\SP_Lab7\Debug\SP_Lab7_Demo.exe “/ MANIFEST: NO / NXCOMPAT /PDB:”C:\Users\apple\Documents\SP_Lab7\Debug\SP_Lab7_Demo.pdb” / DYNAMICBASE “kernel32.lib” “user32.lib” “gdi32.lib” “winspool.lib” “comdlg32.lib” “advapi32.lib” “shell32.lib” “ole32.lib” “oleaut32.lib” “uuid.lib” “odbc32.lib” “odbccp32.lib” / MACHINE: X86 / SAFESEH: NO / INCREMENTAL: NO /PGD:”C:\Users\apple\Documents\SP_Lab7\Debug\SP_Lab7_Demo.pgd “/ SUBSYSTEM: WINDOWS / MANIFESTUAC: “level = ‘asInvoker’ uiAccess = ‘false'” /ManifestFile:”Debug\SP_Lab7_Demo.exe.intermediate.manifest “/ ERRORREPORT: PROMPT / NOLOGO / TLBID: 1

Если я комментирую call print , то все выполняется нормально (даже функция Windows API). Есть ли способ вызвать функцию C из asm-файла без создания файла cpp, который включает ? Можно ли это сделать?

Microsoft реорганизовала большую часть C- среды исполнения и библиотек в VS 2015. Некоторые функции больше не экспортируются из библиотеки C (некоторые из них определены в файле заголовка C ). У Microsoft есть некоторые библиотеки совместимости, такие как legacy_stdio_definitions.lib и legacy_stdio_wide_specifiers.lib , но вы также можете использовать старый набор инструментов платформы Visual Studio 2013 со старыми библиотеками C.

Чтобы изменить набор инструментов платформы: вытащите меню « Project ; выберите Properties... ; перейдите в « Configuration Properties / General и смените « Platform Toolset на Visual Studio 2013 (v120)

Похоже, что можно использовать набор инструментов Visual Studio 2015 с несколькими изменениями.

  • Вам нужно будет добавить эти библиотеки в свои зависимости: libcmt.lib , libvcruntime.lib , libucrt.lib , legacy_stdio_definitions.lib . В качестве альтернативы вы можете использовать includelib для включения этих библиотек в файл сборки.
  • Укажите соглашение о вызове C для main процедуры с помощью PROC C
  • В конце вашего файла (и это важно) не используйте end main , используйте только end . Не устранение этого может привести к непредвиденным сбоям.
  • Хотя мы можем использовать ExitProcess для выхода из нашего приложения, мы также можем поместить код возврата в EAX и выполнить возврат ret . C runtime вызывает нашу main функцию, и мы будем вызывать код останова для нас по возвращении.

Код может выглядеть так:

 .586 .model flat, stdcall option casemap:none includelib libcmt.lib includelib libvcruntime.lib includelib libucrt.lib includelib legacy_stdio_definitions.lib ExitProcess PROTO return:DWORD extern printf:NEAR .data text BYTE "Text", 0 .code main PROC C ; Specify "C" calling convention push offset text call printf add esp, 4 ; invoke ExitProcess,0 ; Since the C library called main (this function) ; we can set eax to 0 and use ret`to have ; the C runtime close down and return our error ; code instead of invoking ExitProcess mov eax, 0 ret main ENDP end ; Use `end` on a line by itself ; We don't want to use `end main` as that would ; make this function our program entry point ; effectively skipping by the C runtime initialization 

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

Библиотека, вероятно, потребует инициализации, и может потребовать, чтобы вы определили кучу буферов где-то для ее хранения.

Вместо того, чтобы идти на все эти проблемы, я предлагаю вам просто придерживаться Windows API, и в вашем случае используйте функцию WriteConsole .

  • Как ссылаться на сборки .NET с помощью PowerShell
  • Как я могу просмотреть MSIL / CIL, сгенерированный компилятором C #? Почему это называется сборкой?
  • Проверьте, равен ли регистр нулю с помощью CMP reg, 0 против OR reg, reg?
  • Почему медленная инструкция цикла? Не удалось ли Intel эффективно внедрить его?
  • Медленная инструкция jmp
  • Код C ++ для проверки гипотезы Collatz быстрее, чем assembly вручную - почему?
  • Как использовать строки в emu8086
  • Цикл с вызовом функции быстрее, чем пустой цикл
  • Как получить вывод ассемблера из источника C / C ++ в gcc?
  • Динамически заменить содержимое метода C #?
  • Почему XCHG reg, reg 3 инструкции по микрооперации на современных архитектурах Intel?
  • Interesting Posts

    DVD-привод исчезает

    Организация загрузки в Google Chrome

    Запуск того же теста JUnit несколько раз с разными данными

    Приложения теряют фокус в течение нескольких секунд в Windows 7

    Значения сумм в одном диапазоне по критерию в другом

    Z-индекс сломан в IE8?

    Сохранение разделенного вкладками файла в Excel без кавычек

    Как использовать class .NET Timer для запуска события в определенное время?

    Компьютер застрял в «Проверка данных пула DMI»

    Что означает «Протокол … может использоваться только как общее ограничение, потому что он имеет« Я »или« связанные с ним требования типа »?

    Ошибка ввода: нет никакого механизма сценария для расширения файла ".vbs"

    Показывать% вместо графов в диаграммах категориальных переменных

    Как сказать PowerShell дождаться окончания каждой команды до начала следующего?

    c ++ сортировка, отслеживающая индексы

    Отключить элементы в JList

    Давайте будем гением компьютера.