gpt4 book ai didi

assembly - 如何在没有计时器的情况下将 ARM Cortex M0+ 延迟 n 个周期?

转载 作者:行者123 更新时间:2023-12-04 17:09:17 25 4
gpt4 key购买 nike

我想将 ARM Cortex M0+ 延迟 n 个周期,而不使用计时器,代码大小尽可能小。 (我认为这要求使用汇编。)

0 个周期的延迟很简单,没有代码。
1 个周期的延迟是一个 NOP。
2 个周期的延迟是两个 NOP。

在什么时候开始循环(代码大小)有效?

最紧密的循环需要多少个循环?什么是设置时间?

发表回答说明:

以下C代码:

register unsigned char counter = 100;
while (counter-- > 0) {
asm("");
}

当用 gcc 和 -O3 编译时给出:
    mov r3, #100
.L5:
sub r3, r3, #1
uxtb r3, r3
cmp r3, #0
bne .L5

这要么说明手动编码 ARM 程序集仍然有目的,或者(更有可能)上面的 C 代码不是将我想要做的事情传达给编译器的最佳方式。

注释?

最佳答案

代码将取决于 n 到底是什么,以及它是否需要动态可变,但给定 the M0+ core's instruction timings ,为特定例程建立界限非常简单。

对于具有固定 8 位立即计数器的最小可能(6 字节)完整循环:

   movs  r0, #NUM    ;1 cycle
1: subs r0, r0, #1 ;1 cycle
bne 1b ;2 if taken, 1 otherwise

NUM=1我们得到最少 3 个循环,每个额外循环加上 3 个循环,直到 NUM=255在 765 个周期(当然,您可以从 NUM=0 进行 2^32 次迭代,但这似乎有点傻)。这使得循环的下限在大约 6 个周期时是实用的。使用固定循环很容易在其中填充 NOP(甚至嵌套循环)以延长每次迭代,并在之前/之后与循环长度的非倍数对齐。如果您可以在需要开始等待之前在寄存器中安排多次迭代准备就绪,那么您可能会丢失初始 mov并且几乎是 3 个或更多周期的任何倍数,减去 1。如果您需要可变延迟的单周期分辨率,则初始设置成本会稍微高一些以纠正剩余部分(我会为此做一个计算分支到 NOP 雪橇)

我假设如果您处于周期关键时间点,您已经中断了(否则在某处为 CPSID 投入另一个周期),并且您没有任何总线等待状态添加额外取指令的周期。

至于尝试在 C 中做到这一点:事实上,你必须在一个空的 asm 中进行黑客攻击。防止“无用”循环被优化掉是一个提示。抽象的 C 机器没有“指令”或“循环”的概念,因此根本无法在语言中可靠地表达这一点。试图依赖特定的 C 结构来编译为合适的指令是非常脆弱的——更改编译器标志;升级编译器;更改一些影响寄存器分配的远程代码,从而影响指令选择;等等 - 几乎任何事情都可能意外地改变生成的代码,所以我想说手工编码的汇编是循环准确代码的唯一明智的方法。

关于assembly - 如何在没有计时器的情况下将 ARM Cortex M0+ 延迟 n 个周期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27510198/

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