【问题标题】:Compiling to ASM on an ARM chip, why are only r1, r2 and r3 registers used在ARM芯片上编译成ASM,为什么只使用r1、r2和r3寄存器
【发布时间】:2013-06-21 10:10:57
【问题描述】:

我刚刚开始研究 Raspberry Pi 上的 ARM 程序集(任何指向优秀文档的链接都会在 cmets 中得到赞赏)

我有一个 C++ 程序,我使用以下命令编译到 Assembler

 g++ -S -fverbose-asm -march=armv6j -mtune=arm1176jzf-s file.cpp

然后我可以检查 file.s,这很好,而且有点道理。但是我认为 ARM 芯片有 15 个通用寄存器我对这段代码的阅读是它只使用 r1 - r3

mov     r3, r3, asl #1  @ tmp166, tmp166,
add     r3, r3, r2      @ tmp166, tmp166, D.24883
mov     r2, r3, asl #3  @ tmp167, tmp166,
add     r3, r3, r2      @ tmp166, tmp166, tmp167
rsb     r2, r3, r1      @ D.24883, tmp166, tmp161

我在生成的代码中看不到出现高于 r3 的寄存器。有什么我从根本上理解的吗?这有充分的理由吗?还是生成的代码不是最优的?

更新

  1. 如果我用-O2 编译它确实使用了更多的寄存器,所以我假设这是GCC 选择做的事情。不太清楚为什么或哪个开关控制此行为。
  2. 我还读到 r1 -r4 可以在不重置其状态的情况下使用,所以我猜对于小函数来说这更有效?

【问题讨论】:

    标签: assembly arm raspberry-pi


    【解决方案1】:

    ARM ABI,在其他处理器家族中并不少见,就是当编译器为目标生成代码时,一些寄存器用于传入参数,一个/一些寄存器用于返回结果,还有一些寄存器不必保留,基本上您可以放心使用它们,如果您需要使用它们,您需要保留的其余寄存器(推入/弹出堆栈)。

    arm 使用 r0-r3 传入参数,使用 r0 返回结果。 r0-r3 也被认为是一次性的(可能还有一个更高的寄存器),所以如果程序足够简单并且不需要太多寄存器,它将尝试使用 r0-r3 来提高性能(不需要使用堆栈)。

    编写高级代码来驱动机器代码是一门艺术形式,您需要了解编译器和处理器等。您走在正确的道路上,但需要编写更多函数来编译和检查生成的机器代码。

    【讨论】:

      【解决方案2】:

      寄存器的使用由两个约束定义,然后它们的使用效率取决于编译器。

      • ABI
      • ARM/Thumb 执行状态

      ABI 是一种约定,顾名思义就是提供二进制兼容性。 ARM ABI,ABI 的一部分定义了哪些寄存器用于函数调用。 ARM ABI 状态 r0-r3 用于函数调用。支持 ARM ABI 的 ARM 编译器需要以这种方式运行,这意味着这是对寄存器使用的约束。

      另一个限制是 ARM/Thumb 执行模式。一些 ARM CPU 可以在 Thumb 执行模式下运行,其中大多数指令只能访问 ARM 内核寄存器的前 8 个寄存器,r0-r7 (ARM ARM 4.1)。这也限制了编译器可以使用多少个寄存器。

      其余取决于编译器的质量、优化模式和调试支持。

      【讨论】:

        【解决方案3】:

        可能您的代码不够复杂,需要更多寄存器。

        【讨论】:

        • 你能不能说的更具体一点,或者这只是一个猜测。
        • 你甚至没有提供'C++'代码,所以这当然是一个猜测
        猜你喜欢
        • 2012-03-29
        • 2015-12-13
        • 1970-01-01
        • 1970-01-01
        • 2012-01-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-09
        相关资源
        最近更新 更多