assembly x64组件-阴影空间

gijlo24d  于 2022-11-13  发布在  其他
关注(0)|答案(1)|浏览(194)

当我从main调用过程时,下面的代码运行得很好。但是如果我从几个过程深处调用过程,堆栈会累积返回地址,从而丢弃堆栈参数的位置。无论在代码中的什么位置调用过程,我如何修改过程,以便在调用之前正确地分配适当的影子空间?
换句话说,我在代码中的几个不同位置调用CreateFile过程,由于堆栈状态的不同,每次调用都需要从rsp中减去不同的字节数才能使其工作。这是不可接受的。我希望有一个无论从哪里调用都能正确工作的过程。

mov rcx, pFileName
mov rdx, GENERIC_READ or GENERIC_WRITE
mov r8, FILE_SHARE_WRITE or FILE_SHARE_READ
xor r9, r9

sub rsp, 110o

mov rax, OPEN_EXISTING
mov qword ptr [rsp + 40o], rax
mov rax, FILE_FLAG_SEQUENTIAL_SCAN
mov qword ptr [rsp + 50o], rax
xor rax, rax
mov qword ptr [rsp + 60o], rax

call CreateFileA
add rsp, 110o
vs3odd8k

vs3odd8k1#

通常的处理方法是保持堆栈对齐。这需要在每个非叶函数中编写代码,将RSP移动8的奇数倍,包括你所做的任何push。你还必须保留额外的32字节,所以如果你没有推任何东西,通常你会在函数的顶部放置sub rsp, 40
不要在任何非叶函数中使用堆栈空间的底部32字节,这个空间将成为你调用的任何函数的影子空间。
您 * 不 * 需要在函数内的每个调用周围修改RSP,只需要在函数的开始/结束处修改。
查看编译器生成的代码以获取示例,例如https://godbolt.org/上的MSVC;另请参见How to remove "noise" from GCC/clang assembly output?
例如Is the caller or callee responsible for freeing shadow store in x64 assembly (windows)?中的GCC输出--它使两个函数调用背对背,call printfcall bar,它们之间不需要任何指令,因为bar不接受参数。

相关问题