x86 ASM 中的简单 Hello World - Windows 控制台

Posted

技术标签:

【中文标题】x86 ASM 中的简单 Hello World - Windows 控制台【英文标题】:Simple Hello World in x86 ASM - Windows console 【发布时间】:2014-08-16 21:36:22 【问题描述】:

我正在尝试在 Windows 下的 x86 程序集中运行以下 Hello Word 示例:

global _main
extern  _GetStdHandle@4
extern  _WriteFile@20
extern  _ExitProcess@4

section.text
_main :
; DWORD  bytes;
mov     ebp, esp
sub     esp, 4

; hStdOut = GetstdHandle(STD_OUTPUT_HANDLE)
push - 11
call    _GetStdHandle@4
mov     ebx, eax

; WriteFile(hstdOut, message, length(message), &bytes, 0);
push    0
lea     eax, [ebp - 4]
push    eax
push(message_end - message)
push    message
push    ebx
call    _WriteFile@20

; ExitProcess(0)
push    0
call    _ExitProcess@4

; never here
hlt
message :
db      'Hello, World', 10
message_end :

但是在尝试链接组装的 .obj 文件时出现以下错误:

错误 LNK2001:无法解析的外部符号 _GetStdHandle@4 错误 LNK2001:无法解析的外部符号 _WriteFile@20 错误 LNK2001:未解析的外部符号 _ExitProcess@4 致命错误 LNK1120:3 个未解决的外部问题

我的例子来源:How to write hello world in assembler under Windows?

如何解决这些问题?或者,为什么这个例子对我不起作用?

【问题讨论】:

http://***.com/questions/20063224/linking-to-kernel32-lib-in-assembler的可能重复 【参考方案1】:

使用 C 编译器时,标准库通常链接到代码,而单独调用链接器时通常不会这样做。

这三个函数位于“kernel32.dll”中,因此您必须链接到“kernel32.lib”(或使用 GNU 工具时的“libkernel32.a”)。

您的入口点是“_main”,所以我假设您也想使用启动目标文件。

但是,在您的情况下这不是必需的,因此您可以简单地将“_main”定义为链接器入口点,而不是链接到启动目标文件。

【讨论】:

是的,我将链接器称为:link /subsystem:console /nodefaultlib /entry:main hello.obj。关于您对 kernel32.lib 的提示:它可以工作,但那是 C 标准库(或者可能是 C++)吗?我实际上是在寻找一种“在没有 C 函数帮助的情况下”在 ASM 中编写 Hello World 的方法(如我提供的源问题中所述)。 kernel32 不是 C 标准库。它是一个提供部分 Windows API 的 Windows 库,如果您想从应用程序与操作系统交互,则需要使用这些 API。 @Michael:事实上,我的示例说会“直接转到 Windows API”,我只是不知道如何包含它。非常感谢。

以上是关于x86 ASM 中的简单 Hello World - Windows 控制台的主要内容,如果未能解决你的问题,请参考以下文章

“呼叫 0x80482f0 <puts@plt>”?只需要澄清 x86 汇编中“hello world”程序中的一行代码

简单的 hello world exec 是 10 KB

x86 asm中的括号是啥意思?

mac的汇编代码(NASM)-hello world

将ffmpeg中的x86 asm和inline-asm编译成WebAssembly的问题

win32汇编hello world