gpt4 book ai didi

c - 使用寄存器和内联汇编 (ARM)

转载 作者:行者123 更新时间:2023-11-30 15:43:48 24 4
gpt4 key购买 nike

我有一个小程序,我试图用它以编程方式识别 CPU 频率。

我的程序结构如下:

  • 设置闹钟
  • while(1) 中递增寄存器循环
  • 计算速度SIGALRM

最初,我使用的是

register unsigned int cycles asm("r6");  
...
while(1)
cycles++;

使用 objdump 后,我注意到这实际上翻译为以下内容:

9aa0:       e1a03006        mov     r3, r6  
9aa4: e2833001 add r3, r3, #1
9aa8: e1a06003 mov r6, r3
9aac: eafffffb b 9aa0 <estimate_from_cycles+0x1cc>

由于我不确定为什么这会转换为 3 条指令,因此我尝试使用内联汇编:

register unsigned int cycles asm("r6");  
...
while(1)
asm("add r6, r6, #1);

这翻译成:

9aa0:       e2866001        add     r6, r6, #1  
9aa4: eafffffd b 9aa0 <estimate_from_cycles+0x1cc>
  • 为什么之前的实现会转换为 3 条指令?
  • 在 ARM 平台上,b <label>指令需要3个周期。然而,ARM 上的减法运算仅使用 1 个周期。
    • 有什么方法可以从 PC 寄存器中减去吗?
    • PC 上也允许减法吗?
    • 是否有其他方法可以减少实现相同逻辑所需的周期数?

编辑:我正在使用 CodeSourcery 的 arm-none-linux-gnueabi- 工具链,没有进行任何优化

最佳答案

该实现很可能会转换为 3 条指令,因为您没有启用任何优化。

但是,从快速测试来看,您似乎无论如何都必须编写内联汇编,因为当我使用 -O3 -fomit-frame-pointer 编译以下内容时

void test(void) {
register unsigned int cycles asm("r6");
while(1) cycles++;
}

例程简单地优化为

00000000 <test>:
0: eafffffe b 0 <test>

即使添加 volatile 也是无用的,因为编译器确信写入CPU寄存器肯定不会有任何副作用(与内存不同),因此对其进行优化是公平的。

回答您的其他问题

  • 有什么方法可以从 PC 寄存器中减去吗?
  • PC 上也允许减法吗?

是的,当然。但我不确定这是否仍然需要一个周期。

  • 是否有其他方法可以减少实现相同逻辑所需的周期数?

顺便说一句,您的逻辑不会给出非常准确的结果,因为您的过程可能会在开始测量和完成测量之间切换。

您期待的是:

<                    your process                     >
|<---------------your alarm duration----------------->|

何时,它可能更像(其中 | 是上下文切换):

<your process> | <other processes ...> | <your process>
|<---------------your alarm duration----------------->|

关于c - 使用寄存器和内联汇编 (ARM),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19719456/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com