Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Visual studio 在Visual Studio中从asm调用C标准库函数_Visual Studio_Assembly_X86_Linker Errors_Masm - Fatal编程技术网

Visual studio 在Visual Studio中从asm调用C标准库函数

Visual studio 在Visual Studio中从asm调用C标准库函数,visual-studio,assembly,x86,linker-errors,masm,Visual Studio,Assembly,X86,Linker Errors,Masm,我在调用visual studio(Win10 x64,visual studio 2015)中创建的asm项目中的C函数时遇到问题。项目由一个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 pu

我在调用visual studio(Win10 x64,visual studio 2015)中创建的asm项目中的C函数时遇到问题。项目由一个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中引用的未解析外部符号\u printf 作用_main@0

链接器输出参数:

/输出:“C:\Users\apple\Documents\SP_Lab7\Debug\SP_Lab7\u Demo.exe” /清单:否/NXCOMPAT /PDB:“C:\Users\apple\Documents\SP_Lab7\Debug\SP_Lab7\u 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 /增量:没有 /PGD:“C:\Users\apple\Documents\SP_Lab7\Debug\SP_Lab7\u Demo.PGD” /子系统:WINDOWS/MANIFESTUAC:“level='asInvoker'uiAccess='false'” /清单文件:“Debug\SP_Lab7_Demo.exe.intermediate.manifest” /ERRORREPORT:PROMPT/NOLOGO/TLBID:1

如果我注释
调用print
,则所有操作都会正常执行(即使是Windows API函数)。有没有办法从asm文件调用C函数而不创建包含
的cpp文件?
可以这样做吗?

您可以调用C函数,但随后需要链接到C库。具体如何实现这一点将取决于您希望链接到哪个C库。我建议找到一个最小的C运行时,比如

该库可能需要初始化,并且可能需要您在某个地方为其簿记定义一组缓冲区


与其麻烦重重,我建议您还是坚持使用Windows API,在您的情况下使用该函数。

Microsoft在VS 2015中重构了大部分C运行时和库。有些函数不再从C库导出(有些是在C头文件中定义的)。Microsoft有一些兼容库,如legacy_stdio_definitions.lib和legacy_stdio_wide_specifiers.lib,但您也可以选择将旧的Visual Studio 2013平台工具集与旧的C库一起使用


要更改平台工具集,请下拉
项目
菜单;选择属性…;转到
配置属性
/
常规
,并将
平台工具集
更改为Visual Studio 2013(v120)

似乎可以通过一些修改来使用Visual Studio 2015工具集

  • 您需要将这些库添加到依赖项中:libcmt.lib、libvcruntime.lib、libucrt.lib、legacy_stdio_definitions.lib。或者,您可以使用
    includelib
    将这些库包括在程序集文件中
  • 使用
    PROC
  • 在文件末尾(这一点很重要),不要使用
    end main
    ,只使用
    end
    。不解决此问题可能会导致意外的崩溃
  • 虽然我们可以使用ExitProcess退出应用程序,但我们也可以将返回代码放入EAX中,并执行
    ret
    返回。C运行时调用我们的
    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

感谢您指向使用WinAPI函数,因为我想要的主要函数是
strcspn
,类似的函数
StrSpn
。但我仍然不明白,为什么
includelib msvcrt.lib
不加载C库。解决方法是将
平台工具集设置为VS2013。为此,请下拉
项目
菜单,选择
属性…
。转到
配置属性
/
常规
,并将
平台工具集
更改为Visual Studio 2013(v120)@MichaelPetch它真的很有效,谢谢Microsoft重构了C运行时的大部分。有些函数不再在库中导出(有些在C头文件中定义)。MS有一些兼容库legacy_stdio_definitions.lib和legacy_stdio_wide_specifiers.lib,但我还没有让printf使用它们,所以我选择使用VS 2013工具集。可能还有其他的解决方法,但我还没有看到。我已经添加了一个新的答案和一个您可能有兴趣尝试的解决方案。它使用Visual Studio 2015工具集。在尝试之前,您必须从Visual Studio 2013工具集切换到2015。如果这对你有用的话,我会很生气的。