在 ARM C 调用约定中保存哪些寄存器? [英] What registers to save in the ARM C calling convention?

查看:33
本文介绍了在 ARM C 调用约定中保存哪些寄存器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

自从我上次编写 arm 汇编程序以来已经有一段时间了,我对细节有点生疏了.如果我从 arm 调用一个 C 函数,我只需要担心保存 r0-r3 和 lr,对吗?

It's been a while since I last coded arm assembler and I'm a little rusty on the details. If I call a C function from arm, I only have to worry about saving r0-r3 and lr, right?

如果 C 函数使用任何其他寄存器,它是否负责将这些寄存器保存在堆栈中并恢复它们?换句话说,编译器将生成代码来为 C 函数执行此操作.

If the C function uses any other registers, is it responsible for saving those on the stack and restoring them? In other words, the compiler would generate code to do this for C functions.

例如,如果我在汇编函数中使用 r10,我不必将其值压入堆栈或内存,并在 C 调用后弹出/恢复它,对吗?

For example if I use r10 in an assembler function, I don't have to push its value on the stack, or to memory, and pop/restore it after a C call, do I?

这是针对 arm-eabi-gcc 4.3.0.

This is for arm-eabi-gcc 4.3.0.

推荐答案

这取决于 ABI 针对您正在编译的平台.在 Linux 上,有两个 ARM ABI;旧的和新的.AFAIK,新的(EABI)实际上是ARM的AAPCS.完整的 EABI 定义目前位于 这里在 ARM 上信息中心.

It depends on the ABI for the platform you are compiling for. On Linux, there are two ARM ABIs; the old one and the new one. AFAIK, the new one (EABI) is in fact ARM's AAPCS. The complete EABI definitions currently live here on ARM's infocenter.

来自 AAPCS,§5.1.1:

  • r0-r3 是参数和暂存寄存器;r0-r1 也是结果寄存器
  • r4-r8 是被调用者保存寄存器
  • r9 可能是一个被调用者保存寄存器(在 AAPCS 的某些变体上它是一个特殊寄存器)
  • r10-r11 是被调用者保存寄存器
  • r12-r15 是特殊寄存器
  • r0-r3 are the argument and scratch registers; r0-r1 are also the result registers
  • r4-r8 are callee-save registers
  • r9 might be a callee-save register or not (on some variants of AAPCS it is a special register)
  • r10-r11 are callee-save registers
  • r12-r15 are special registers

被调用者必须保存被调用者保存的寄存器(与调用者保存寄存器相反,调用者保存寄存器);所以,如果这是你正在使用的 ABI,你不必在调用另一个函数之前保存 r10(另一个函数负责保存它).

A callee-save register must be saved by the callee (in opposition to a caller-save register, where the caller saves the register); so, if this is the ABI you are using, you do not have to save r10 before calling another function (the other function is responsible for saving it).

您使用的编译器没有区别;特别是 gcc 可以为几个不同的 ABI 配置,甚至可以在命令行上进行更改.查看它生成的序言/结尾代码并不是那么有用,因为它是为每个函数量身定制的,编译器可以使用其他方式来保存寄存器(例如,将它保存在函数).

Which compiler you are using makes no difference; gcc in particular can be configured for several different ABIs, and it can even be changed on the command line. Looking at the prologue/epilogue code it generates is not that useful, since it is tailored for each function and the compiler can use other ways of saving a register (for instance, saving it in the middle of a function).

术语:callee-save"是non-volatile"或call-preserved"的同义词:什么是被调用者和调用者保存的寄存器?
进行函数调用时,您可以假设 r4-r11(可能除了 r9)中的值在(调用保留)之后仍然存在,但不适用于 r0-r3(调用破坏/易失性).

Terminology: "callee-save" is a synonym for "non-volatile" or "call-preserved": What are callee and caller saved registers?
When making a function call, you can assume that the values in r4-r11 (except maybe r9) are still there after (call-preserved), but not for r0-r3 (call-clobbered / volatile).

这篇关于在 ARM C 调用约定中保存哪些寄存器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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