解释推送和弹出循环

时间:2014-01-12 00:54:08

标签: assembly push masm pop masm32

现在,我使用汇编语言进行自学并使用MASM32。但是,我不了解一些代码行。我需要一个更好的解释。

mov eax,20
loop1: 
push eax 
invoke StdOut, addr HelloWorld 
pop eax 
dec eax 
jnz loop1

如果没有推送和弹出,它将打印出'Hello World'无限!

我的问题:

  

为什么我们必须推送和弹出eax寄存器?

     

StdOut是否在内部更改该寄存器的值?

3 个答案:

答案 0 :(得分:1)

因为对STDOUT例程的调用会更改EAX寄存器(也许这不是唯一的...)

答案 1 :(得分:1)

你说得对。在调用可能更改一个或多个寄存器的子例程之前,标准做法是在调用子例程之前将它们推送到堆栈中,它们将被保留。子程序返回后,以相反的顺序从堆栈中弹出值并将它们存储回原始寄存器。

答案 2 :(得分:0)

当您调用子程序无法保证您感兴趣的寄存器时,这是一种常见做法;所以,你将它们保存在堆栈(推送)并在通话后将它们取回(弹出)。

在某些情况下,可能会保留函数以保留一些寄存器,但“划伤”其他寄存器。当您知道存在此类约定时,您可以选择寄存器而不是其他寄存器以避免push/pop模式。 (通过推送必须保留的寄存器,并在返回调用者之前弹出它们,简单地在被调用者中完成交易。)

E.g。当您在x86计算机上调用C标准库(“cdecl”生效)的函数时,您需要保存“仅”eaxecx和{{1}如果你需要保持他们的价值观。