Основная проблема, с которой вы сталкиваетесь с alink, заключается в том, что у него нет 64-битной поддержки, поэтому вам пришлось использовать nasm -fwin32
для генерации 32-битного объектного кода.Вторая проблема заключается в том, что вы не указали точку входа.Разочарование, не правда ли?Я потратил много времени на разные линкеры.
Если вы хотите выполнить сборку win64 с помощью nasm, я предлагаю использовать golink .Требуется легкий, быстрый, без излишеств подход к созданию ссылок.Если вы хотите использовать функции из DLL в своем коде, вам не нужны какие-либо библиотечные файлы - GoLink может выполнять все ссылки, используя только сами DLL-файлы.Это даже вытянет их из системного пути, поэтому вам не нужно помещать что-либо в ту же папку, что и исходный код.
Следующая серьезная проблема, с которой вы столкнулись, заключается в том, что ваш пример кода не 'T подходит для 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, заключается в вызовах API Windows (WriteFile, ExitProcess, GetStdHandle).Аналогично, msvcrt.dll предназначен для стандартных функций библиотеки C (например, printf, malloc и т. Д.).Если вы хотите действительно разобраться в сборке Win64, вы, вероятно, захотите пойти дальше и просто использовать Windows API, оставляя без внимания msvcrt.dll.Вы можете найти документацию по всем функциям Windows API и структурам данных на MSDN .
Наконец, стоит отметить, что многие прототипы и структуры функций, которые они предоставляют в MSDN, предназначены для 32-битного Windows API, поэтому всякий раз, когда вы видите DWORD, вы, вероятно, захотите использовать вместо него QWORD..
Во всяком случае, я надеюсь, что это заставит вас начать в том направлении, куда вы хотите идти.Удачи!