我正在尝试使用 VS 2010 附带的 ML 和 LINK 在 Windows 上编译一个 hello world。
.MODEL FLAT
.STACK 4096
.data
msg db "Hello World!",0
.code
INCLUDELIB MSVCRT
EXTRN printf:NEAR
EXTRN exit:NEAR
PUBLIC _main
_main PROC
mov eax, offset msg
push eax
call printf
mov eax,0
push eax
call exit
_main ENDP
END _main
我不断收到链接器错误,指出 printf 和 exit 是未解析的外部符号。我有几个问题。
- 可与 ML 和 LINK 一起使用哪些命令行选项来编译和解决错误消息。
- 是否有另一种方法可以使用汇编代码将文本输出显示到屏幕,而不是调用 printf 等 C 运行时函数?
最佳答案
- 您需要对 C 函数使用下划线名称,因为这就是编译器在汇编时发出它们的方式 级别。
- 在调用 printf 和其他 CRT 函数后,您应该清理堆栈,因为它们使用 cdecl 调用约定(调用者堆栈清理)。严格来说,您也应该在 _exit 之后执行此操作,但这并不重要,因为它永远不会返回。
- 要使用 CRT 函数,您必须初始化 CRT。您可以在文件
VC\crt\src\crt0.c
中检查它是如何完成的
这是一个对我有用的最小文件(我使用静态库,因为我有 VS2008,并且不想摆弄 list 以使其与 DLL 一起工作)。
.386
.MODEL FLAT
.STACK 4096
.data
msg db "Hello World!",0
.code
INCLUDELIB LIBCMT
EXTRN _printf:NEAR
EXTRN _exit:NEAR
EXTRN __heap_init:NEAR
EXTRN __mtinit:NEAR
EXTRN __ioinit:NEAR
PUBLIC _main
_main PROC
push 1
call __heap_init
add esp, 4
push 1
call __mtinit
add esp, 4
call __ioinit
mov eax, offset msg
push eax
call _printf
pop ecx
mov eax,0
push eax
call _exit
_main ENDP
END _main
对于 MSVCRT,初始化是不同的,例如您需要调用 set_app_type
要不依赖 CRT,您必须使用操作系统 API。对于 Win32,这将是 Win32 函数,例如 WriteFile(使用 GetStdHandle(STD_OUTPUT_HANDLE) 作为文件句柄)。查看一些示例 here .
关于hyperlink - x86 masm Hello World ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3902697/