为什么在使用堆栈框架操作时 ebx、esi 和 edi 不可用?

Why are ebx, esi and edi unusable when operating with a stackframe?

在汇编中创建函数时,我在操作如此少的寄存器时遇到问题 - 这些寄存器中有什么阻止我使用它们?我可以在编码时将它们的内容复制到参数中并在退出函数之前将其重置以不破坏其目的吗?

Why are ebx, esi and edi unusable

这完全取决于平台使用的 ABI 和 calling conventions,不过,碰巧大多数编译器都符合寄存器 eaxecxedx 与其他寄存器不同,在函数调用中被认为是易变的。

Can I copy their contents into a parameter while coding and reset it before exiting the function to not break its purpose?

是的,事实上,它是 x86 代码中一个非常常见的习惯用法,用于恢复本应在函数调用中保留的寄存器,如下所示:

my_fn:
    push ebx
    push esi


    ; code ...

    pop esi
    pop ebx
    ret

假设 ; code ... 部分没有使堆栈失衡,esiebx 在离开函数之前恢复到它们的旧值。