显然,联机64位Windows汇编程序教程确实有效,但是,关键的链接器标志
/entry
和
/[subsystem:]console
被吉特·巴什弄坏了。因此,我采用了在PowerShell调用中包装链接器调用的保护措施,以确保链接器(golink或link.exe)使用正确的模式console,无论哪个shell环境运行链接器命令。
vsexec.bat版本:
:: Execute the specified command within a Visual Studio context,
:: where the necessary environment variables are sufficiently configured.
::
:: Usage: vsexec.bat <command>
::
:: Requires a Command Prompt or PowerShell context to operate.
call "C:\\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" amd64 %*
你好。阿斯姆:
extern GetStdHandle
extern WriteFile
extern ExitProcess
section .rodata
msg db "Hello World!", 0x0d, 0x0a
msg_len equ $-msg
stdout_query equ -11
status equ 0
section .data
stdout dw 0
bytesWritten dw 0
section .text
global start
start:
mov rcx, stdout_query
call GetStdHandle
mov [rel stdout], rax
mov rcx, [rel stdout]
mov rdx, msg
mov r8, msg_len
mov r9, bytesWritten
push qword 0
call WriteFile
mov rcx, status
call ExitProcess
构建步骤:
$ nasm -f win64 hello.asm
$ powershell -Command "~\\vsexec.bat link /entry:start /subsystem:console hello.obj kernel32.lib"
$ hello.exe
Hello World!
最后注意:我不确定什么是正确的堆栈和返回策略。Windows文档建议堆栈A)与16字节对齐,B)为每个Windows API调用提供32字节,C)执行
ret
在每个子程序的末尾。然而,当我尝试这样做时,我会得到segfaults。不确定nasm/link.exe是否代表我自动执行一些堆栈管理工作,或者什么,我想我可以检查一下
objdump -xDz hello.exe
输出以进一步检查。