它已经有一段时间,因为我最后一编码臂汇编和我有点生锈的详细信息。如果我呼叫一个C职能从手臂,我只需要担心节省r0-r3和lr,对吗?

如果C功能使用的任何其他登记,它是负责保存那些在栈和恢复他们?换句话说,编译器将产生的代码这样做C功能。

例如,如果我使用r10在汇编程功能,我没有推动其价值在堆,或存储器,并pop/后恢复一个C呼叫我?

这是手臂-不想动旧的程序也-海湾合作委员会4.3.0.

有帮助吗?

解决方案

它取决于 ABI 该平台汇编。在Linux上,有两个手臂ABIs;旧的和新的一个。据我所知,新的人(不想动旧的程序也)事实上是手臂的AAPCS.完全不想动旧的程序也定义目前的生活 在这里,手臂上的信息中心.

该AAPCS,§5.1.1:

  • r0-r3 是的论点和划登记册; r0-r1 也是结果寄存器
  • r4-r8 都被叫保存寄存器
  • r9 可能是一个被叫保存登记或不(在某些变体AAPCS这是一个特殊的登记册)
  • r10-r11 都被叫保存寄存器
  • r12-r15 特别寄存器

一个被叫保存登记册必须保存的被叫方(在反对一个呼叫保存登记册,那里的呼叫者保存的登记册);所以, 如果 这是阿比,你使用的你没有保存r10话之前的另一个功能(其他职能是负责保存它)。

编辑: 哪个编译器您使用的是没有差异;海湾合作委员会特别是可以将配置于几个不同的ABIs,它甚至可以改变的命令行。看在序言/尾声码它会产生是不是有用的,因为它是专门为每个功能 编译器可以使用其他方式保存一个登记册(例如,保存在中间的一个功能)。

其他提示

加起来失踪的信息在霓虹灯寄存器:

该AAPCS, 第5.1.1核心寄存器:

  • r0-r3 是的论点和划登记册; r0-r1 也是结果寄存器
  • r4-r8 都被叫保存寄存器
  • r9 可能是一个被叫保存登记或不(在某些变体AAPCS这是一个特殊的登记册)
  • r10-r11 都被叫保存寄存器
  • r12-r15 特别寄存器

从AAPCS,§5.1.2.1照片登记册的用法公约:

  • s16–s31(d8–d15、问4–7) 必须保留的
  • s0–s15(d0–d7,a0–3)d16–d31(8–15) 不需要被保留

原职:
手臂-c-呼叫-《公约》-霓虹灯-寄存器-以保存

64位的手臂,A64 (从呼吁程序标准手臂64位的建筑)

有三十一个,64位,一般用途(integer)寄存器可见的A64指示设置;这些都是标记 r0-r30.在64位下这些寄存器通常被称为使用名称 x0-x30;在一个32位方面的注册规定,通过使用 w0-w30.此外,一个叠指登记册, SP, ,可以使用的有限数量的指令。

  • SP 堆的指针
  • r30 LR登记的链接
  • r29 FP框架的指针
  • r19...r28 被叫方保存的寄存器
  • r18 该平台登记,如果需要;否则一个临时的注册。
  • r17 IP1第二内部程序的呼吁临时登记(可以用 通过呼叫单板和专利法条约码);在其他时间可以用作一个 临时登记。
  • r.16 IP0第一内部程序-调头开始登记册(可通过电话 单板和专利法条约码);在其他时间可以用作一个 临时登记。
  • r9...r15 临时寄存器
  • r8 间接导致位置寄存器
  • r0...r7 参/结果寄存器

第八寄存器, r0-r7, 是用来通过的参数值的成一个子程序,并为返回的结果值从一个功能。他们也可以用来举行的中间值在程序(但是,在一般情况下,只之间的电子程序).

寄存器 r.16(IP0)r17(IP1) 可以使用通过连接作为一个头开始登记册之间的例行和任何子程序,它呼吁。它们也可以用在例行举行的中间值之间的子程序的呼吁。

的作用的登记册 r18 是的平台具体的。如果一个平台,ABI有需要的专用通用登记册进行间程序状态(例如,线上下文)然后,它应该使用这个登记册,用于这一目的。如果平台ABI没有这样的要求,那么就应该使用r18作为一个额外的临时登记。该平台ABI规范必须提供文件的使用对于该登记册。

单指令

手臂64位结构也有进一步的三十二个寄存器, 0-v31, ,这可以使用的单指令和浮点运算。的确切名称登记册将变更指示的尺寸的访问。

注: 不像在AArch32,在AArch64的128位和64位景的一个单指令和浮点登记不重叠的多个登记在一个狭窄看, 所以q1,d1和s1所有提到相同的入口在登记册的银行。

第八寄存器, 0-版本7, 是用来通过的参数值的成一个子程序,并为返回的结果值从一个功能。他们也可以用来举行的中间值在程序(但是,在一般情况下,只之间的电子程序).

寄存器 v8-v15 必须保留由一个被叫跨子程序;剩余的寄存器(0-版本7,16缸-v31)不需要保留(或应当保留通过呼叫者).此外,仅仅底的64位的每一个值存在 v8-v15 需要保留;这是责任的呼叫者,以保留更大价值。

答案的CesarB和帕维尔提供报价,从AAPCS,但问题依然存在。不会被拯救r9?什么约r12?什么约r14?此外,这些问题的答案是非常一般性的和不具体的手臂-不想动旧的程序也作为工具的请求。这是一个实用的方法,以找出其登记册是被呼叫者保存的,哪些不是。

以下C码包含一个内联会,要求修改寄存器r0-r12和r14。编译器将产生的代码保存登记册需要通过ABI。

void foo() {
  asm volatile ( "nop" : : : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14");
}

使用命令行 arm-eabi-gcc-4.7 -O2 -S -o - foo.c 并添加关于你的平台(例如 -mcpu=arm7tdmi 例如)。该命令将打印所产生的大会上的代码STDOUT。它可能看起来是这样的:

foo:
    stmfd   sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
    nop
    ldmfd   sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
    bx  lr

请注意,编译器而产生的代码保存和恢复r4-r11。编译器不保存r0-r3、r12。它恢复r14(别名lr)纯粹是偶然的,因为我从经验中知道,退出的代码可能还载保存lr入r0然后做一个"bx r0"而不是"bx lr".无论是通过加入 -mcpu=arm7tdmi -mno-thumb-interwork 或者通过使用 -mcpu=cortex-m4 -mthumb 我们得稍微不同的会代码看起来是这样的:

foo:
    stmfd   sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
    nop
    ldmfd   sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc}

再次,r4-r11的保存和恢复。但r14(别名lr)是不可恢复的。

以总结:

  • r0-r3 被叫方保存的
  • r4-r11被叫方保存的
  • r12(别名ip) 被叫方保存的
  • r13(别名sp)被叫方保存的
  • r14(别名lr)是 被叫方保存的
  • r15(别名pc)的程序计数和设置的价值lr现有的功能呼叫

这个拥有至少手臂-不想动旧的程序也-海湾合作委员会的默认。有的命令行开关(特别是的-复关),可能会影响的结果。

至少在Cortex M3架构中,功能调用和中断也存在差异。

如果发生中断,它将自动将R0-R3,R12,LR,PC压入堆栈,并在返回时从IRQ自动POP返回。如果在IRQ例程中使用其他寄存器,则必须手动将它们推送到堆栈。

我不认为这个自动PUSH和POP是用于函数调用(跳转指令)。如果约定说R0-R3只能用作参数,结果或临时寄存器,那么就不需要在函数调用之前存储它们,因为函数返回后不应该使用任何值。但与中断相同,如果在函数中使用它们,则必须存储所有其他CPU寄存器。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top