如果只是为了这个目的,编写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位代码的调用约定有些复杂,而且您不能在64位代码中使用MASM的invoke
。工作代码不会变得非常复杂,但让代码正常运行可能需要更多的工作。总体思路是对于64位代码,您需要在堆栈上为所有参数分配空间,但是前N个小到足以放入寄存器的参数将进入寄存器。