1

这是源代码的副本:

extrn MessageBoxA: PROC
extrn ExitProcess: PROC

.data
mytit db 'The 64-bit world of Windows & assembler...', 0
mymsg db 'Hello World!', 0

.code
main proc
mov r9d, 0       ; uType = MB_OK
lea r8,  mytit   ; LPCSTR lpCaption
lea rdx, mymsg   ; LPCSTR lpText
mov rcx, 0       ; hWnd = HWND_DESKTOP
call MessageBoxA
mov ecx, eax     ; uExitCode = MessageBox(...)
call ExitProcess
main endp

End

现在,我只是想让我的“第一个”x64 汇编程序启动并运行,这样我就可以开始玩耍并实际学习一些汇编,所以我只是从这里复制了这个源代码,试图看看我是否能得到任何可以正确组装的东西,但到目前为止,还没有运气。

如果我组装它,我不会得到任何错误,无论是在组装时还是运行时,但程序没有按预期运行:它似乎根本没有做任何事情。一旦生成了可执行文件并双击它,什么也没有发生,如果我转到任务管理器,它似乎也没有在后台运行。这是怎么回事?

我正在使用 MASM64 的默认设置,这些设置是在检查“构建自定义...”下的“masm”时生成的(通过右键单击解决方案资源管理器中的项目来找到)并在配置管理器中将平台从 Win32 更改为 x64,例外情况是我已将“入口点”链接器选项更改为“main”,将“子系统”链接器选项更改为“Windows”。(所有这些都在 Visual Studio 2012 中完成。)

在 Visual Studio 中运行程序生成的调试信息是

'Hello World (ASM).exe' (Win32): Loaded 'D:\Google Drive\My Documents\Visual Studio 
2012\Projects\Hello World (ASM)\x64\Release\Hello World (ASM).exe'. Symbols loaded.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\ntdll.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\kernel32.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\KernelBase.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\user32.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\gdi32.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\imm32.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\msctf.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\msvcrt.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\nvinitx.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\advapi32.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\sechost.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\rpcrt4.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Program Files\NVIDIA Corporation\coprocmanager\detoured.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Program Files\NVIDIA Corporation\coprocmanager\Nvd3d9wrapx.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\setupapi.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\cfgmgr32.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\devobj.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Program Files\NVIDIA Corporation\coprocmanager\nvdxgiwrapx.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\PROGRA~1\NVIDIA~1\NVSTRE~1\rxinput.dll'. Module was built without symbols.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\ole32.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\oleaut32.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Loaded 'C:\Windows\System32\combase.dll'. Cannot find or open the PDB file.
'Hello World (ASM).exe' (Win32): Unloaded 'C:\PROGRA~1\NVIDIA~1\NVSTRE~1\rxinput.dll'
'Hello World (ASM).exe' (Win32): Unloaded 'C:\Windows\System32\combase.dll'
'Hello World (ASM).exe' (Win32): Unloaded 'C:\Windows\System32\oleaut32.dll'
'Hello World (ASM).exe' (Win32): Unloaded 'C:\Windows\System32\ole32.dll'
First-chance exception at 0x000007FA9A09B9FB (gdi32.dll) in Hello World (ASM).exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
Unhandled exception at 0x000007FA9A09B9FB (gdi32.dll) in Hello World (ASM).exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
First-chance exception at 0x000007FA9A09B9FB (gdi32.dll) in Hello World (ASM).exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
Unhandled exception at 0x000007FA9A09B9FB (gdi32.dll) in Hello World (ASM).exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
First-chance exception at 0x000007FA9A09B9FB (gdi32.dll) in Hello World (ASM).exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
Unhandled exception at 0x000007FA9A09B9FB (gdi32.dll) in Hello World (ASM).exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
The program '[1080] Hello World (ASM).exe' has exited with code 0 (0x0).
4

1 回答 1

4

在调用任何 WinAPI 函数之前,您必须在堆栈上提供一些空间:

sub rsp,40

在 Windows 上调用 x64 代码中的其他函数时,您需要为该函数提供 shadow/spill/home 空间,这是一个可以溢出用于传递前 4 个参数 ( ECX, EDX, R8, R9) 的 4 个寄存器的区域。四个四字相当于 32 个字节(它始终是 32 个字节,即使您调用的函数需要少于 4 个参数)。

那么为什么要减去 40 而不是 32?堆栈对齐也有要求。在调用函数之前,您必须将堆栈指针对齐到 16 字节的倍数(在进入函数时,您还将RIP在堆栈上,制作RSP % 16 == 8)。所以减去 8 个额外字节是因为程序启动时堆栈指针是 8 模 16。总是这样吗?我不知道,但如果调用程序入口点(操作系统或某些运行时库)的人也在call.

而不是sub rsp,40你可以使用:

and esp,0xFFFFFFF0   ; align
sub rsp,32           ; allocate shadow space 
于 2013-08-08T06:26:27.300 回答