问题描述
我正在尝试使用VS 2010附带的ML和LINK在Windows上编译一个hello world。
I am trying to compile a hello world on windows with the ML and LINK that ship with VS 2010.
.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
I继续得到链接器错误,说printf和exit是未解析的外部符号。我有几个问题。
I keep getting linker errors saying that printf and exit are unresolved external symbols. I have a couple of questions.
- 使用ML和LINK编译和解决错误消息的命令行选项是什么。
- 是否有另一种方法可以使用汇编代码向屏幕显示文本输出,而不是像printf那样调用c运行时函数?
推荐答案
- 您需要为C函数使用下划线名称,因为这是编译器在汇编
级别上发出它们的方式。 - 您应该在调用printf和其他CRT函数后清理堆栈,因为它们使用cdecl调用约定(调用者堆栈清理)。严格来说,你也应该在_exit之后做,但这不太重要,因为它永远不会返回。
- 要使用CRT函数,你必须初始化CRT。您可以在文件
VC\crt\src\crt0.c
- You need to use underscored names for C functions, since that's how the compiler emits them on assemblylevel.
- You should clean up the stack after calling printf and other CRT functions, since they use cdecl calling convention (caller stack cleanup). Strictly speaking you should do it after _exit too, but that's less important since it never returns.
- To use CRT functions you have to initialize CRT. You can check how it's done in the file
VC\crt\src\crt0.c
中检查它是如何完成的
这是一个适合我的最小文件(我使用静态库,因为我有VS2008并且不想使用清单来使其与DLL一起使用)。
Here's a minimal file that worked for me (I used static library because I have VS2008 and didn't want to fiddle with manifests to make it work with 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
For MSVCRT the initialization is different, e.g. you need to call set_app_type
要不依赖CRT,你必须使用OS API。在Win32的情况下,将是Win32函数,如WriteFile(文件句柄使用GetStdHandle(STD_OUTPUT_HANDLE))。请参阅中的一些示例。
To not rely on CRT, you have to use the OS APIs. In case of Win32 that would be Win32 functions such as WriteFile (with GetStdHandle(STD_OUTPUT_HANDLE) for the file handle). See some examples here.
这篇关于x86 masm你好世界的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!