2010-03-12 49 views
3

我是初学者学习某个程序集的时候,在函数调用之前保留ESP寄存器时,如果通过加或减操作,它会影响吗?很难解释,考虑以下在功能调用后保留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的调用做到这一点,但消息框似乎解决ESP给我吗?我怎么知道什么功能需要这个,哪些不需要?

回答

4

是的,当使用esp时(在这种情况下,减去,但有时在引用堆栈中的某些东西时需要添加时,如函数中的参数),正确使用符号很重要。原因在于堆栈在内存中向下增长为。这与我们通常如何看待堆栈(您将事物置于顶部并将其从顶部移除)相反,在内存中,随着堆栈增长,这将是更高和更高的地址。但X86(以及大多数其他处理器)上的调用堆栈实际上正在向下增长。这就像在板块的底部添加板块并从底部移除它们一样......在内存中,随着更多东西被添加到堆栈中,地址越来越低。

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

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

+0

非常丰富的谢谢 – Daniel 2010-03-12 01:06:26

1

另外我怎么会需要做这样的调用像sprintf,但MessageBox似乎为我解决ESP?

这是因为MessageBox()函数在返回时从堆栈中清除参数。它可以做到这一点,因为参数的数量是固定的。

但是,sprintf()函数被调用的参数数量是可变的。该函数不知道调用者可能推送到堆栈的数量,因此当调用返回时,调用者有责任清除它们。

+0

啊我看到这是有道理的,谢谢你的输入 – Daniel 2010-03-12 01:06:56