Я советую вам найти инструмент, поддерживающий ASM в стиле Intel, а не ужасный синтаксис AT&T.
Для этого вы ничего не получите, написав 64-битный код - вы также можете придерживаться 32-битного кода.
Если вы хотите выводить в MessageBox, это может выглядеть так:
.386
.MODEL flat, stdcall
MessageBoxA PROTO near32 stdcall, window:dword, text:near32,
windowtitle:near32, style:dword
.stack 8192
.data
message db "Hello World!", 0
windowtitle db "Win32 Hello World.", 0
.code
main proc
invoke MessageBoxA, 0, near32 ptr message, near32 ptr windowtitle, 0
ret
main endp
end main
Если вы хотите выводить на консоль, это (как ни странно) немного сложнее:
.386
.MODEL flat, stdcall
getstdout = -11
WriteFile PROTO NEAR32 stdcall, \
handle:dword, \
buffer:ptr byte, \
bytes:dword, \
written: ptr dword, \
overlapped: ptr byte
GetStdHandle PROTO NEAR32, device:dword
ExitProcess PROTO NEAR32, exitcode:dword
.stack 8192
.data
message db "Hello World!"
msg_size equ $ - offset message
.data?
written dd ?
.code
main proc
invoke GetStdHandle, getstdout
invoke WriteFile, \
eax, \
offset message, \
msg_size, \
offset written, \
0
invoke ExitProcess, 0
main endp
end main
Теоретически переход на 64-битный код не делает не имеет большого значения - например, вы можете использовать одни и те же функции в обоих. На самом деле это немного болезненно, потому что соглашение о вызовах для 64-битного кода довольно сложно, и вы не можете использовать MASM invoke
для 64-битного кода. Рабочий код не был бы целым намного более сложным, но заставить его работать, вероятно, потребовалось бы немного больше усилий. Общая идея заключается в том, что для 64-битного кода вы выделяете место в стеке для всех ваших параметров, но первые N параметров, которые достаточно малы, чтобы поместиться, входят в регистры.
В fasm :
include 'win32axp.inc'
.code
start:
invoke AllocConsole
invoke WriteConsole,<invoke GetStdHandle,STD_OUTPUT_HANDLE>,tex,tex.size,dummy,0
invoke Sleep,-1
.end start
.data
tex TCHAR 'Hello World!'
.size = ($-tex)
dummy rd 1