问题描述
自从我上次编码手臂汇编程序以来已经有一段时间了,我对细节有些不了解.如果我从手臂调用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).
编辑:所使用的编译器没有区别;特别是可以为几个不同的ABI配置gcc,甚至可以在命令行上对其进行更改.查看它生成的序言/结尾代码不是很有用,因为它是针对每个函数定制的,并且编译器可以使用其他方式保存寄存器(例如,将其保存在寄存器中间).功能).
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"是非易失性"或保留呼叫"的同义词:
进行函数调用时,可以假定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调用约定中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!