在ARM芯片上编译为ASM,为什么只使用r1,r2和r3寄存器

时间:2013-06-21 10:10:57

标签: assembly arm raspberry-pi

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

我有一个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可以在不重置状态的情况下使用,所以我觉得小功能这个效率更高?

3 个答案:

答案 0 :(得分:1)

ARM ABI,对于其他处理器系列来说并不罕见,当编译器为目标生成代码时,一些寄存器用于传入参数,一个/一些寄存器用于返回结果,一些寄存器不必保留,基本上你可以毫无顾虑地使用它们,并且如果你需要使用它们,你需要保留其他寄存器(推/弹/堆栈)。

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

制作高级代码来驱动机器代码是一种你需要了解编译器和处理器等的艺术形式。你是在正确的道路上但需要编写更多的函数来编译和检查生成的机器代码。 / p>

答案 1 :(得分:1)

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

  • ABI
  • ARM / Thumb执行状态

ABI是一种惯例,正如其名称所建议的那样提供二进制兼容性。 ARM ABI,ABI的一部分定义了哪些寄存器用于函数调用。 ARM ABI个状态r0-r3用于函数调用。支持ARM ABI的ARM编译器需要以这种方式运行,这意味着这是对寄存器使用的约束。

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

休息取决于编译器,优化模式和调试支持的质量。

答案 2 :(得分:0)

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