使用 alink 链接 .obj 文件

发布于 2024-12-03 11:25:53 字数 750 浏览 1 评论 0原文

我为 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 文件是 这里

i wrote a helloworld program for win64 and converted it to a .obj file using nasm...now i have to load the resultant hello.obj file using alink but errors are cropping...

to assemble i used the command

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

(this executed successfully)

and to load i am writing

alink hello.obj 

but the error which is continuously showing is

loading file hello.obj 
unknown file type

then once i wrote -f win32 instead of -f win64...
and then when i executed the same loading code for alink(i.e. alink hello.obj) the screen wrote

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

the helloworld.asm file is here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦里°也失望 2024-12-10 11:25:53

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

< code>golink /console example64.obj kernel32.dll msvcrt.dll

请注意,我们包含 kernel32.dll 的原因是为了 Windows API 调用(WriteFile、ExitProcess、获取标准句柄)。同样,msvcrt.dll 用于标准 C 库函数(即 printf、malloc 等)。如果您想真正深入了解 Win64 程序集,您可能会想直接使用 Windows API,而忽略 msvcrt.dll。您可以找到所有 Windows API 函数和数据结构的文档

最后,值得注意的是,他们在 MSDN 上提供的许多函数原型和结构都是针对 32 位 Windows API 的,因此每当您看到 DWORD 时,您可能会想使用 QWORD 来代替。

不管怎样,我希望这能让你开始朝着你想要的方向前进。祝你好运!

The major problem you're having with alink is that it doesn't have any 64-bit support, which is why you had to use nasm -fwin32 to generate 32-bit object code. The second problem is that you haven't specified an entry point. Frustrating, isn't it? I wasted a lot of time with different linkers myself.

If you want to do win64 assembly with nasm, I suggest using golink. It takes the light, fast, no-nonsense approach to linking. If you want to use functions from a DLL in your code, you don't need any library files -- GoLink can do all the linking using just the DLL files themselves. It'll even pull them off the system path, so you don't need to put anything in the same folder as your source code.

The next major problem you're having is that your example code isn't suited for Windows. Here's one that you can use to get started that won't crash when you run it:

; 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

Assuming it's saved as example64.s, you can assemble and link it like so:

nasm -fwin64 example64.s

golink /console example64.obj kernel32.dll msvcrt.dll

Note that the reason we include kernel32.dll is for the Windows API calls (WriteFile, ExitProcess, GetStdHandle). Likewise, msvcrt.dll is for standard C library functions (i.e. printf, malloc, etc.). If you want to get really down and dirty with Win64 assembly, you'll probably want to go ahead and just use the Windows API, leaving out msvcrt.dll. You can find documentation for all the Windows API functions and data structures on MSDN.

Finally, it's worth noting that a lot of the function prototypes and structures they give on MSDN are for the 32-bit Windows API, so whenever you see a DWORD, you'll probably want to use a QWORD instead.

Anyway, I hope that gets you started in the direction you want to go. Good luck!

霓裳挽歌倾城醉 2024-12-10 11:25:53

如果您仍然想使用 ALINK,您可以尝试以下操作:

  • 汇编 win32 程序(用 32b 代码编写!):

    nasm -f obj 文件名.asm
    
  • 汇编 win64 程序(用 64b 代码编写!):

    nasm -f win64 file_name.asm
    

现在,32b 对象的链接过程:

alink -oPE -subsys con -entry Start file_name.obj

其中 Start 是程序的入口点,即您声明为全局的程序。

对于 64b 对象,请尝试另一个链接编辑器,例如 goLink,正如 James 建议的那样。

这应该可以做到。希望它也适合你!

If you still want to use ALINK you could try this:

  • to assemble a win32 program (written in 32b code!):

    nasm -f obj file_name.asm
    
  • to assemble a win64 program (written in 64b code!):

    nasm -f win64 file_name.asm
    

Now, the linking process for the 32b object:

alink -oPE -subsys con -entry Start file_name.obj

Where Start is the entry point for your program, the one that you declared global.

For the 64b object, try another link-editor like goLink, as James suggested.

This should do it. Hope it works for you too!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文