2010-10-10 161 views
2

我试图编译在与ML窗口一个Hello World和链接,船舶用VS 201086 MASM的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和退出都无法解析的外部符号。我有一些问题。

  1. 什么是命令行选项与ML和LINK一起使用来编译和解决错误消息。
  2. 是否有另一种方法显示文本输出到屏幕使用汇编代码,而不是调用像printf的c运行时功能?

回答

4
  1. 您需要使用的C函数下划线的名称,因为这是编译器如何发出它们装配 水平。
  2. 您应该在调用printf和其他CRT函数后清理堆栈,因为它们使用cdecl调用约定(调用者堆栈清理)。严格地说你也应该在_exit之后去做,但那不重要,因为它永远不会返回。
  3. 要使用CRT功能,您必须初始化CRT。你可以检查它是如何的文件VC\crt\src\crt0.c

这里是为我工作的最小文件中完成(我用静态库,因为我有VS2008,不想与舱单摆弄,使其与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,你必须使用OS API。如果Win32是Win32函数,例如WriteFile(对于文件句柄使用GetStdHandle(STD_OUTPUT_HANDLE))。看到一些例子here

+0

Hi Igor,你能告诉我如何链接__mtinit,__ioinit ...我试过CL/MT final.obj /链接kernel32.lib msvcrt.lib但它不能工作... – computereasy 2014-02-19 18:48:35