为啥程序会汇编,但啥也不做?

Posted

技术标签:

【中文标题】为啥程序会汇编,但啥也不做?【英文标题】:Why does the program assemble, but do nothing?为什么程序会汇编,但什么也不做? 【发布时间】:2013-08-07 04:58:21 【问题描述】:

这是源代码的副本:

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 复制了这个源代码,试图看看我是否可以正确组装任何东西,但到目前为止,还没有运气。

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

我正在使用 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).

【问题讨论】:

您遇到运行时错误;访问冲突。使用调试器单步执行代码以查看发生这种情况的位置。这可能与调用 Win32 函数之一有关。 您链接到的那个网站上的 FASM 代码也不起作用,所以我不知道我对他的 MASM 代码有多少信任。无论如何,您不想在堆栈上为MessageBoxA 函数分配一些影子空间吗?也就是说,以sub rsp,32 之类的内容启动程序。 应该是sub rsp,40,而不是32。 另外,如果你想学习 x64 汇编,我强烈建议你 these tutorials。它们是我学习装配的方式,因此我可以为它们担保;他们非常好。 @Michael - 你应该让你的答案,这样我就可以投票了。当然,64 位 Windows 要求用户自己进行调用堆栈分配。这就是这段代码中的错误。我非常熟悉它,因为我从相同的演示代码开始,并且必须自己解决堆栈问题。 :-) 【参考方案1】:

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

sub rsp,40

在 Windows 上以 x64 代码调用其他函数时,您需要为该函数提供 shadow/spill/home 空间,这是一个可以溢出用于传递前 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 

【讨论】:

以上是关于为啥程序会汇编,但啥也不做?的主要内容,如果未能解决你的问题,请参考以下文章

在 vue 3 中获取会停止后端,并且在一次正常工作后啥也不做

为啥调试我的asp.net网站时有时会弹出反汇编程序/反汇编窗口?

Linux系统里如何编译汇编程序。

汇编语言-其他转移指令CALL

8086汇编 jcxz 指令

MKOverlayView 性能问题。啥也不做。但慢