链接到KERNEL32.LIB汇编 [英] Linking to Kernel32.lib in assembler
问题描述
我开始学习今天的组装和已经跑在Linux上的许多测试,效果很不错!我搬到了我的电脑,并开始尝试在这里写一些。当试图调用外部函数(这再次,精细的工作在Linux上),我会得到LINK 2001年未解决的外部错误,告诉我,WriteConsoleA与NASM编译后没有定义时,我遇到了一个问题:
I started learning assembly today and have ran many tests on linux that worked very well! I moved over to my PC and started to attempt to write some here. I ran into a problem when attempting to call external functions (which again, worked fine on linux) where I would get LINK 2001 Unresolved External errors telling me that WriteConsoleA is not defined when after compiling with nasm:
nasm -f win32 test.asm -o test.obj
和与cl.exe时:
cl test.obj /link libcmt.lib kernel32.lib
我得到这些错误:
I get these errors:
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
从<复制的几乎一模一样
href=\"http://stackoverflow.com/questions/12574924/hello-world-using-nasm-in-windows-assembly\">here.
任何帮助深表AP preciated!谢谢!
Copied almost exactly from here. Any help is much appreciated! Thanks!
推荐答案
首先,CL不是一个链接,但一个编译器。为什么不使用GoLink为您链接到后显示我?这是很容易使用。您可以使用LD作为连接器,但你的实习医生会改变一点。
First off, cl is not a linker but a compiler. Why not just use GoLink as I shown in the post you linked to? It is much easier to use. You could use ld as the linker, but your externs will change a bit.
Windows API函数使用的函数名的装饰 - 下划线+ FunctionName + @sizeof参数,这是一个连接东西
Windows API functions use function name decorations - an underscore + FunctionName + @sizeof parameters, this is a linker thing.
所以,ExitProcess的是真正导出为_ExitProcess @ 4,因为它需要1 DWORD参数。 WriteConsoleA需要5个参数DWORD大小,所以这将是_WriteConsole @ 20
So, ExitProcess is really exported as _ExitProcess@4 since it takes 1 DWORD parameter. WriteConsoleA takes 5 parameters DWORD sized, so it would be _WriteConsole@20
更改code为:
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目录是一个不错的选择是:
-LC:\\ Program Files文件\\微软的SDK \\ WINDOWS \\ V6.0 \\ Lib文件
To link with ld, tell it where the lib directory is, a good bet is: -L "C:\Program Files\Microsoft SDKs\Windows\v6.0\Lib"
然后就用 -l </ code>标志与图书馆
-l KERNEL32
then just use the -l
flag with the library
-l kernel32
使用NASM和LD为您的样品code我生成文件:
My makefile using NASM and ld for your sample code:
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函数名。
If you were to use GoLink as in the other post, you could just use the API Function names as they appear in the docs.
这篇关于链接到KERNEL32.LIB汇编的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!