以下是来源的副本:
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汇编程序启动并运行,以便我可以开始玩并实际学习一些汇编,所以我只是简单地从here复制了这个来源。试图看看我是否可以得到任何正确的装配,但到目前为止,没有运气。
如果我收集它,我不会在汇编时或运行时都没有出现任何错误,但程序没有按预期运行:它似乎根本没有做任何事情。生成可执行文件后,我双击它,没有任何反应,如果我去任务管理器,它似乎也没有在后台运行。发生了什么事?
我使用那些在“建立自定义...”下,选中“MASM”生成MASM64的默认设置(通过发现右键单击Solution Explorer中的项目),并从Win32的改变平台,在到x64配置管理器,例外情况是我已将“入口点”链接器选项更改为“主”,将“子系统”链接器选项更改为“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).
答案 0 :(得分:4)
在调用任何WinAPI函数之前,必须在堆栈上提供一些空间:
sub rsp,40
在Windows上调用x64代码中的其他函数时,您需要为该函数提供阴影/溢出/归属空间,该区域可以溢出用于传递前4个参数的4个寄存器( ECX, EDX, R8, R9
)。四个四字组共计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