程序为什么要汇编,但什么都不做?

时间:2013-08-07 04:58:22

标签: visual-studio assembly visual-studio-2012 masm

以下是来源的副本:

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).

1 个答案:

答案 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