1

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

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

 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 可以在不重置其状态的情况下使用,所以我猜对于小功能,这更有效?
4

3 回答 3

1

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

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

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

于 2013-06-21T15:01:23.653 回答
1

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

  • 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)。这也限制了编译器可以使用多少个寄存器。

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

于 2013-06-21T16:59:09.997 回答
0

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

于 2013-06-21T10:42:53.207 回答