繁体   English   中英

x86汇编器-哪些寄存器要推送?

[英]x86 Assembler - Which registers to push?

x86汇编程序例程通常以以下序言开头:

push        ebp                ; Save ebp
mov         ebp, esp           ; Set stack frame pointer
sub         esp, localbytes    ; Allocate space for locals
push        <registers>        ; Save registers

我已经看到函数push 1到4个寄存器push任何地方。

除了推送ebp (这是必需的)之外,什么决定您是否还要推送ediesi和/或ebx

你应该一直推动他们吗? 我找不到为我解决此问题的参考。

推送没有修改的寄存器没有任何意义。 除此之外,您还可以选择保留哪些寄存器。 采用某种约定,以便调用代码和被调用代码都知道它负责什么。

您会看到调用方与被调用方保存寄存器 基本思想是,如果要将值存储在保存有被调用方的寄存器中,则需要将其当前值保存在某个位置,以便可以在函数调用结束时将其恢复。

此Wikipedia部分可能会有所帮助: http : //en.wikipedia.org/wiki/X86_calling_conventions#Register_preservation

一般而言,您会保留每个寄存器,但明确告知您不必保留的寄存器除外。 如果使用32位代码进行调用,则不必保留EAX,ECX或EDX,但是必须保留其他所有内容。 在64位代码中,有更多寄存器,因此您也必须保留它们。

在您的示例中,您必须推送EBP,因为您对其进行了更改。 在编写程序集以使用EBP索引参数时,这很常见。 将参数压入堆栈,然后压入返回地址。 因此,要获取参数,您必须访问堆栈。 如果ESP发生了变化,那么记住参数相对于ESP的位置将是一个巨大的痛苦。 因此,我们使用EBP保存了一个“书签”。

但是,如果您不需要这样做,那就不要! 例如,Microsoft使用的__fastcall调用约定将传递ECX中的第一个参数。 我有简单的代码,永远不会将任何内容推入堆栈,而仅使用EAX和ECX。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM