为什么 IA-32 有一个非直观的调用者和被调用者寄存器保存约定? [英] Why does IA-32 have a non-intuitive caller and callee register saving convention?

查看:20
本文介绍了为什么 IA-32 有一个非直观的调用者和被调用者寄存器保存约定?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

IA-32 的通用调用约定说:

The common calling conventions for IA-32 say:

• Callee-save registers
%ebx, %esi, %edi, %ebp, %esp
Callee must not change these.  (Or restore the caller's values before returning.)

• Caller-save registers
%eax, %edx, %ecx, condition flags
Caller saves these if it wants to preserve them.  Callee can freely clobber.

为什么会存在这个奇怪的约定?为什么不在调用另一个函数之前保存所有寄存器?或者让被调用者使用 pusha/popa 保存和恢复所有内容?

Why does this strange convention exist? Why not save all the registers before calling another function? Or have the callee save and restore everything with pusha/popa?

推荐答案

为什么要编写代码来保存每个可能不需要的函数中的寄存器?这将为每个函数调用添加额外的代码和额外的内存写入.它现在可能看起来并不重要,但在 80 年代创建此公约时,它可能确实很重要.

Why would you want to write code to save registers in every function that you might not need? That would add extra code and extra memory writes to every single function call. It may not seem significant now, but back in the 80's when this convention was created it probably did matter.

请注意,ia-32 没有固定的调用约定——你列出的只是一个外部约定——ia-32 没有强制执行它.如果您正在编写自己的代码,则可以随意使用寄存器.

And note that ia-32 doesn't have a fixed calling convention - what you list is only an external convention - ia-32 doesn't enforce it. If you're writing your own code you use the registers however you wish.

另见讨论调用约定的历史 在旧的新事物博客.

Also see the discussion History of Calling Conventions at the Old New Thing Blog.

在决定哪些寄存器应该由调用保留时约定,您需要平衡调用者的需求与被叫方的需求.调用者希望所有寄存器都是保留,因为这消除了调用者担心的需要通过调用保存/恢复值.被叫方更喜欢不保留寄存器,因为这样就不需要保存进入时的值并在退出时恢复它.

When deciding which registers should be preserved by a calling convention, you need to balance the needs of the caller against the needs of the callee. The caller would prefer that all registers be preserved, since that removes the need for the caller to worry about saving/restoring the value across a call. The callee would prefer that no registers be preserved, since that removes the need to save the value on entry and restore it on exit.

如果你需要保留的寄存器太少,那么调用者就会变成填充了注册保存/恢复代码.但是如果你需要太多寄存器被保存,然后被调用者有义务保存和恢复调用者可能并不真正关心的寄存器.这对于叶函数(执行不调用任何其他函数).

If you require too few registers to be preserved, then callers become filled with register save/restore code. But if you require too many registers to be preserved, then callees become obligated to save and restore registers that the caller might not have really cared about. This is particularly important for leaf functions (functions that do not call any other functions).

这篇关于为什么 IA-32 有一个非直观的调用者和被调用者寄存器保存约定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆