2011-09-08 85 views
0

我写了一个win64的helloworld程序,并使用nasm将其转换为.obj文件...现在我必须使用alink加载生成的hello.obj文件,但错误裁剪...链接.obj文件与链接

组装我使用的命令

nasm -f win64 -o hello.obj helloworld.asm 

(这个成功执行)

和加载我写

alink hello.obj 

但持续显示错误是

loading file hello.obj 
unknown file type 

然后一次我写的Win32 -f代替-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

您的汇编语言程序是为32位Linux编写的,因此,即使您整理了对象格式并链接了问题,您也会得到一个只会崩溃的程序。如果在我今晚回家后没有人回答你的问题,我会在win64的nasm-style程序集中编写一个示例Hello World,并用链接指示发布它。 –

回答

1

你与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。

无论如何,我希望能让你开始朝着你想去的方向发展。祝你好运!

+0

谢谢你,我知道你写了很多时间已经过去了,但这是一个很大的帮助,再次感谢。 – Ophelia

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 

从哪里开始是你的程序,你声明的全局的一个入口点。

对于64B对象,尝试另一个链接编辑器一样goLink,詹姆斯建议。

这应该这样做。希望它也适用于你!