2010-10-10 155 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