Win32 NASM HelloWorld 使用 Printf 导致访问冲突

Win32 NASM HelloWorld using Prinft results in AccessViolation

刚刚阅读了很多教程,并认为我会在 Windows 上尝试使用 NASM。我尝试了几个简单的 "Hello World" 版本,其中一个应该使用 _printf 函数将文本打印到标准输出。

代码如下:

; Build by doing:
; nasm -f win32 -o test.o test.asm
; link /SUBSYSTEM:CONSOLE libcmt.lib test.o

section .text
    global _start   
    extern _printf 

_start:
    push msg      ; Push msg on stack
    call _printf  ; Call printf
    add  esp, 4   ; Reset the stack 

    ; return 0
    xor eax, eax
    ret

; Our string, null terminated
msg: db "Hello World ", 13,10,0

我按照描述使用 "nasm -f win32 -o test.o test.asm" 构建了它,并将其与 Microsoft Visual Studio 2013 链接器链接。到目前为止运行良好,但是一旦我尝试 运行 可执行文件,我就会遇到访问冲突。使用的确切链接器命令:

link /subsystem:console /LIBPATH:"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\lib" /LIBPATH:"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Lib" /nodefaultlib /entry:start test.o libcmt.lib kernel32.lib

我已尽最大努力使用 OllyDBG 来解决错误,但这也无济于事。也许这里有人有想法?...

此致

呸,...回答我自己! 经过长时间的研究和调试,我们开始吧!

使用 _printf 和静态链接到 "libcmt.lib" 确实需要 CRT 初始化。动态链接时,这似乎是自动完成的。

所以唯一要做的就是:

/entry:mainCRTStartup 

将入口点更改为 "mainCRTStartup",以便在调用实际 "main" 函数之前初始化所有内容。有点遗憾的是,版本 12 中的 Visual Studio 库 "libcmt.lib" 没有 return 任何有意义的信息,但因访问冲突而崩溃,而版本 10 有 return:

runtime error R6030 - CRT not initialized

问题已解决。搞笑,...也很烦人