gpt4 book ai didi

winapi - 在汇编程序中链接到 Kernel32.lib

转载 作者:行者123 更新时间:2023-12-02 01:08:18 25 4
gpt4 key购买 nike

我今天开始学习汇编,并在 linux 上运行了很多测试,效果非常好!我搬到了我的电脑上,开始尝试在这里写一些东西。我在尝试调用外部函数(再次在 Linux 上运行良好)时遇到问题,我会收到 LINK 2001 Unresolved External 错误,告诉我在使用 nasm 编译后未定义 WriteConsoleA:

nasm -f win32 test.asm -o test.obj

和 cl.exe:

cl test.obj /link libcmt.lib kernel32.lib

我收到这些错误:

test.obj : error LNK2001: unresolved external symbol ExitProcess
test.obj : error LNK2001: unresolved external symbol GetStdHandle
test.obj : error LNK2001: unresolved external symbol WriteConsoleA
test.exe : fatal error LNK1120: 3 unresolved externals

程序集:

extern ExitProcess, GetStdHandle, WriteConsoleA
NULL equ 0
STD_OUTPUT_HANDLE equ -11
section .data
msg db "Hello world!",0xa
msgLen equ $-msg
section .bss
dummy resd 1
section .text
global _main
_main:
push STD_OUTPUT_HANDLE
call GetStdHandle
push NULL
push dummy
push msgLen
push msg
push eax
call WriteConsoleA
push NULL
call ExitProcess

几乎完全复制自 here .任何帮助深表感谢!谢谢!

最佳答案

首先,cl 不是链接器而是编译器。为什么不像我在您链接到的帖子中显示的那样使用 GoLink?它更容易使用。您可以使用 ld 作为链接器,但您的 externs 会稍微改变。

Windows API 函数使用函数名装饰 - 一个下划线 + FunctionName + @sizeof 参数,这是一个链接器的东西。

因此,ExitProcess 实际上导出为 _ExitProcess@4,因为它需要 1 个 DWORD 参数。 WriteConsoleA 采用 DWORD 大小的 5 个参数,因此它将是 _WriteConsole@20

将您的代码更改为:

extern _ExitProcess@4, _GetStdHandle@4, _WriteConsoleA@20

%define ExitProcess _ExitProcess@4
%define GetStdHandle _GetStdHandle@4
%define WriteConsoleA _WriteConsoleA@20

NULL equ 0
STD_OUTPUT_HANDLE equ -11
section .data
msg db "Hello world!",0xa
msgLen equ $-msg

section .bss
dummy resd 1

section .text
global _main
_main:
push STD_OUTPUT_HANDLE
call GetStdHandle

push NULL
push dummy
push msgLen
push msg
push eax
call WriteConsoleA

push NULL
call ExitProcess

要与 ld 链接,告诉它 lib 目录在哪里,一个不错的选择是:-L "C:\Program Files\Microsoft SDKs\Windows\v6.0\Lib"

然后只需在库中使用 -l 标志-l kernel32

我的 makefile 使用 NASM 和 ld 作为您的示例代码:

APP= Sample

all: $(APP) clean

$(APP): $(APP).obj
"C:\MinGW\bin\ld" $(APP).obj -o $(APP).exe -L "C:\Program Files\Microsoft SDKs\Windows\v6.0\Lib" -l kernel32

$(APP).obj: $(APP).asm
nasm -f win32 $(APP).asm -o $(APP).obj

clean:
rm $(APP).obj

如果您要像在另一篇文章中那样使用 GoLink,您可以只使用文档中显示的 API 函数名称。

关于winapi - 在汇编程序中链接到 Kernel32.lib,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20063224/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com