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”程序中的一行代码