我为win64编写了一个helloworld程序,并使用nasm将其转换为.obj文件...现在我必须使用alink加载生成的hello.obj文件,但错误正在裁剪...
组装我使用了命令
nasm -f win64 -o hello.obj helloworld.asm
(这已成功执行)
加载我写作
alink hello.obj
但是连续显示的错误是
loading file hello.obj
unknown file type
然后我写了-f win32而不是-f win64 ... 然后当我为alink执行相同的加载代码(即alink hello.obj)时,屏幕写了
loading file hello.obj
matched externs
matched comdefs
warning,no entry point specified
warning-no stack
error:target address out of frame
base=00000010, target=00000000
helloworld.asm文件为here
答案 0 :(得分:2)
您对alink的主要问题是它没有任何64位支持,这就是您必须使用nasm -fwin32
生成32位目标代码的原因。第二个问题是您没有指定入口点。令人沮丧,不是吗?我自己浪费了很多时间与不同的连接器。
如果你想用nasm进行win64程序集,我建议使用golink。它采用轻松,快速,严谨的方式进行链接。如果要在代码中使用DLL中的函数,则不需要任何库文件--GoLink可以仅使用DLL文件本身进行所有链接。它甚至会将它们从系统路径中拉出来,因此您不需要将任何内容放在与源代码相同的文件夹中。
您遇到的下一个主要问题是您的示例代码不适合Windows。这是你可以用来开始的一个,当你运行它时不会崩溃:
; example64.s
; nasm -fwin64 example64.s
; golink /console example64.obj kernel32.dll msvcrt.dll
bits 64
default rel
extern GetStdHandle
extern WriteFile
extern ExitProcess
extern printf
section .data
message db 'Hello, World!',10,0
msglen equ $-message
written dq 1
section .text
global Start ; GoLink will use Start as the default entry point
Start:
; Use the C library to print our message
mov rcx, message
call printf
; Now try using the Windows API
mov rcx, -11
call GetStdHandle
; Use WriteFile to print our message again.
; Notice the calling convention for 64-bit Windows uses
; rcx, rdx, r8, and r9 for the first 4 non-floating point arguments
; and then the rest are pushed onto the stack.
mov rcx, rax ; HANDLE hFile
mov rdx, message ; LPCVOID lpBuffer
mov r8, msglen ; DWORD nNumberOfBytesToWrite
mov r9, written ; LPDWORD lpNumberOfBytesWritten
push qword 0 ; LPOVERLAPPED lpOverlapped
call WriteFile
mov rcx, 0
call ExitProcess
假设它保存为example64.s,您可以像这样组装和链接它:
nasm -fwin64 example64.s
golink /console example64.obj kernel32.dll msvcrt.dll
请注意,我们包含kernel32.dll的原因是针对Windows API调用(WriteFile,ExitProcess,GetStdHandle)。同样,msvcrt.dll用于标准C库函数(即printf,malloc等)。如果你想让Win64程序集变得非常简单和肮脏,你可能希望继续使用Windows API,而忽略了msvcrt.dll。您可以找到所有Windows API函数和数据结构on MSDN的文档。
最后,值得注意的是,他们在MSDN上提供的许多函数原型和结构都是针对32位Windows API的,所以每当你看到一个DWORD时,你可能会想要使用QWORD。
无论如何,我希望能让你开始朝着你想要的方向前进。祝你好运!
答案 1 :(得分:0)
如果您仍想使用ALINK,可以试试这个:
组装一个win32程序(用32b代码编写!):
nasm -f obj file_name.asm
组装一个win64程序(用64b代码编写!):
nasm -f win64 file_name.asm
现在,32b对象的链接过程:
alink -oPE -subsys con -entry Start file_name.obj
其中Start是您的程序的入口点,即您声明为global的入口点。
对于64b对象,请尝试另一个像goLink这样的链接编辑器,如James建议的那样。
这应该这样做。希望它也适合你!