x86 masm你好世界

时间:2010-10-10 23:50:34

标签: hyperlink x86 masm

我正在尝试使用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是未解析的外部符号。我有几个问题。

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

1 个答案:

答案 0 :(得分:4)

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

    这是一个适合我的最小文件(我使用静态库,因为我有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