简体   繁体   English

如何在 Windows 上编译 Hello World 程序集?

[英]How to compile a Hello World assembly on Windows?

Having such a simple assembly Win 32 program:有这么一个简单的assembly Win 32程序:

.386
.model flat, stdcall
option casemap :none

EXTERN printf :PROC ; declare printf

.data
    HelloWorld db "Hello Wolrd!:-)", 0

.code
start:
  sub esp, 4
  push offset HelloWorld
  call printf
  add esp, 4
  ret
end start

I can successfully compile it by just:我可以通过以下方式成功编译它:

ml.exe /c HelloWorld.asm

BUT have a problem linking it.但是链接它有问题。 When I use:当我使用:

link HelloWorld.obj libcmt.lib

I'm getting an error:我收到一个错误:

unresolved external symbol _main called in _mainCRTStartup

What have I change/correct to to successfully link the program to run it?我要更改/更正什么才能成功链接程序以运行它?

PS聚苯乙烯

Please don't tell me to use just nasm .请不要告诉我只使用nasm I'd like to use ml & link from my MSVC.我想使用我的 MSVC 中的ml & link

With some minor tweaks this now builds correctly.通过一些小的调整,现在可以正确构建。

.386    
.model flat, c
option casemap :none

includelib libcmt.lib
includelib legacy_stdio_definitions.lib

EXTERN printf :PROC ; declare printf

.data
    HelloWorld db "Hello World!:-)", 0

.code
main PROC
  push offset HelloWorld
  call printf
  add esp, 4
  ret
main ENDP
END

The main edits are主要编辑是

  • .model flat, c sets the calling conventions for procedures to C. .model flat, c将过程的调用约定设置为 C。
    If you decide to keep .model flat, stdcall it'll require these changes.如果您决定保持.model 平坦,则 stdcall将需要这些更改。

Replace代替

EXTERN printf :PROC

main PROC 

with

printf PROTO NEAR C,:DWORD

main PROC NEAR C    
  • Included libcmt.lib and legacy_stdio_definitions.lib which statically links the native C-Runtime startup into your code.包括libcmt.liblegacy_stdio_definitions.lib ,它们将本机 C 运行时启动静态链接到您的代码中。

  • Changed entry point from start to main .将入口点从start更改为main There's an entry point (_mainCRTStartup) within the C-Runtime library (CRT) libcmt.lib, which does some initialization tasks, and then hands off control to the entry point for your application main . C 运行时库 (CRT) libcmt.lib 中有一个入口点 (_mainCRTStartup),它执行一些初始化任务,然后将控制权交给应用程序main的入口点。 You can change the default entry point, but usually you want the convenience of the initialization the CRT entry point does for you automatically.您可以更改默认入口点,但通常您希望 CRT 入口点自动为您进行初始化的便利性。

  • Removed the first sub esp,4 so the remaining one push is balanced by the add esp,4, so ESP is pointing at the return address when ret runs.删除了第一个sub esp,4,因此剩余的一次推送由 add esp,4 平衡,因此当 ret 运行时,ESP 指向返回地址。

To build, open a Windows command prompt and run:要构建,请打开 Windows 命令提示符并运行:

"C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvars32.bat"

to set the MSVC Environment initialized for: 'x86'设置初始化为:'x86'的 MSVC 环境

Next, run these MASM commands接下来,运行这些 MASM 命令

ml.exe /c /coff HelloWorld.asm

link.exe /SUBSYSTEM:console HelloWorld.obj

The program displays程序显示

Hello World!:-)你好,世界!:-)

Your error message says that it can't find the exported symbol (ie function) "_main".您的错误消息说它找不到导出的符号(即函数)“_main”。 I expect renaming your start function to _main would get it to compile.我希望将您的 start 函数重命名为 _main 会使其编译。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM