繁体   English   中英

C 函数调用的 ARM 汇编函数中的寄存器使用

[英]Register usage in ARM assembly function which is called by a C function

ARM 的 C 函数调用约定说:

  • 调用者将在 r0-r3 中传递前 4 个参数。
  • 调用者将在堆栈上传递任何额外的参数。
  • 调用者将从 r0 获取返回值。

我正在手工编写一个由 C 调用的汇编函数。原型相当于:

void s(void);

假设 C 函数c()调用s()

由于s()没有参数也没有返回值。 我相信r0-r3不会被编译器触及来生成c()调用s()的调用序列。

假设s()将使用r0-r12来完成其功能。 c()也有可能使用这些寄存器。

我不确定是否必须明确保存和恢复s()涉及的所有寄存器,比如r0-r12 这样的内存操作会花费一些时间。

或者至少我不必为r0-r3这样做?

来自Arm 架构的过程调用标准,第 6.1.1 节(第 19 页):

子程序必须保留寄存器 r4-r8、r10、r11 和 SP(以及将 r9 指定为 v6 的 PCS 变体中的 r9)的内容

所以是的,因为 r0-r3 是临时寄存器,您不需要在s()使用它们之前保存它们,但是您必须保存和恢复任何其他寄存器。

假设编译器符合 ARM ABI,然后像这样声明s()

extern void s(void);

应该就足够了,并且编译器不应该在调用s()之后发出依赖于c()函数中先前的 r0-r3 值的代码(即c()应该在调用s()之前根据需要保存 r0-r3 和之后恢复它们),因为这会破坏 ABI 合规性。

通常,在混合 C 和 asm 时,您永远无法对 C 代码使用的寄存器做出任何假设,除了那些保证被调用约定堆叠的寄存器。 在使用它们之前堆叠所有其他寄存器,然后稍后弹出它们。 所有这些都取决于编译器在调用汇编程序函数时在内部做出和没有做出的假设。

这里有一些不错的信息: Mixing C, C++, and Assembly Language

暂无
暂无

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

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