gpt4 book ai didi

assembly - 初学者学习汇编在函数调用后保留 esp

转载 作者:行者123 更新时间:2023-12-02 22:11:46 28 4
gpt4 key购买 nike

我是一个学习汇编的初学者,在函数调用之前保留 ESP 寄存器时,通过加法或减法来实现是否重要?很难解释,请考虑以下内容

mov esi, esp
sub esp, 12 // on 32bit OS this would mean that there are 3 arguments to the function
// push, function call etc
cmp esi, esp // should be the same

mov esi, esp
// push, function call etc
add esp, 12
cmp esi, esp // should be the same

此外,如果由于某种原因 cmp 失败,执行 mov esp, esi 重新对齐堆栈是否安全?

谢谢

编辑:另外,为什么我需要对像 sprintf 这样的调用执行此操作,但 MessageBox 似乎为我修复了 ESP?我如何知道哪些功能需要这个,哪些不需要?

最佳答案

是的,在使用 esp 时确保符号正确非常重要(在本例中是减法,但有时在引用堆栈上已有的内容时还需要添加,例如函数内的参数)。其原因是堆栈在内存中向下增长。这与我们通常对堆栈的看法相反(将东西放在顶部并将它们从顶部移除),在内存中,随着堆栈的增长,地址会越来越高。但 X86(以及大多数其他)处理器上的调用堆栈实际上是向下增长的。这就像将盘子添加到堆栈的底部,然后将它们从底部删除......在内存中,随着越来越多的东西添加到堆栈中,地址会变得越来越低。

是的,将值更改为 esp 是安全的,只要您确定将其设置为堆栈内的有效位置,并且只要您确定不需要任何这样做你会失去的信息。在这种情况下,您将 esp 保存在 esi 中正是出于这个原因...您可以从 esi 恢复 esp,因此无论之前的函数调用做了什么,您都知道 esp 就在您想要的位置。

sprint 和 MessageBox 之间的区别在于“调用约定”。这告诉高级语言 (C) 在调用堆栈帧和寄存器时如何处理它们。 sprintf 是 cdecl ,而 MessageBox 是 stdcall .

关于assembly - 初学者学习汇编在函数调用后保留 esp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2429700/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com