本文介绍了x86 masm你好世界的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用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.


  1. 使用ML和LINK编译和解决错误消息的命令行选项是什么。

  2. 是否有另一种方法可以使用汇编代码向屏幕显示文本输出,而不是像printf那样调用c运行时函数?


推荐答案


  1. 您需要为C函数使用下划线名称,因为这是编译器在汇编
    级别上发出它们的方式。

  2. 您应该在调用printf和其他CRT函数后清理堆栈,因为它们使用cdecl调用约定(调用者堆栈清理)。严格来说,你也应该在_exit之后做,但这不太重要,因为它永远不会返回。

  3. 要使用CRT函数,你必须初始化CRT。您可以在文件 VC\crt\src\crt0.c

  1. You need to use underscored names for C functions, since that's how the compiler emits them on assemblylevel.
  2. 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.
  3. 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你好世界的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-17 15:15