assembly 在X64组装件中,ret x与add rsp,x

qlvxas9a  于 2023-03-02  发布在  其他
关注(0)|答案(1)|浏览(174)

我在用MASM 64写程序,我经常用WinAPI,pushpop指令我不用,我用mov [rsp + x]代替,我不使用局部变量,不使用prolog/epilog,根本不使用rbp,我使用sub rsp, x来保留阴影空间,并保持堆栈16字节对齐。用ret xadd rsp, x结束一个过程有什么区别?我知道他们都给rsp加了值来清理堆栈。性能有什么区别吗?我猜ret x会更快,因为在add rsp, x之后无论如何都会有一个ret

p4tfgftt

p4tfgftt1#

假设在堆栈上有55、44、33、22、11(从上到下),还有64位整数。
在这种情况下,ret 0x20将返回到地址55,然后从堆栈中移除其他四个值,而add rsp, 0x20; ret将首先从堆栈中移除四个值,然后返回到地址11
在这两种情况下,总共从堆栈中移除五个值,但两种情况下的返回地址不同。
既然你说你用add rsp, x从函数内部为局部变量创建空间,你需要后一种情况(add rsp, x; ret),另一种情况是删除 caller 在调用函数之前压入的函数参数。
主流的x86-64调用约定都不使用被调用方弹出约定,所以x86-64代码使用普通的ret,并保留已分配的堆栈参数,调用方可以重用该空间进行另一次调用。
一些32位约定是被调用方弹出,如stdcall和fastcall,使用ret n。i386 System V和cdecl是调用方弹出约定。

相关问题