【问题标题】:Develop loop in ARM assemblyARM 汇编中的开发循环
【发布时间】:2017-09-27 02:26:09
【问题描述】:

我必须编写一个程序,将寄存器 X、Y 和 Z 初始化为零,然后循环 10 次,每次将寄存器 X 加 1。如果寄存器 X 为偶数,则将寄存器 Y 加一,如果寄存器 X 可整除乘以 3,寄存器 Z 加一。

我写了一些代码,但我不确定它是否正确,如果有任何反馈,我将不胜感激。

       R0, #0
       R1, #0
       R2, #0
 Loop: R3, #0
       CMP R0, #10
       BEQ endif
       ADD R0, #1
       TST R0, #1
       ADDEQ R1, #1
       MOV R3, R0 MOD 3
       CMP R3, #0
       ADDEQ R2, #1
       B loop
 Endif:

【问题讨论】:

  • 你可以在 cmets 上重一点吗?
  • 代码审查问题确实属于codereview.stackexchange.com。如果您不确定它是否正确,那么您应该对其进行测试以查看它是否有效。如果它在您的测试中有效,请将其发布在 codereview 上。如果没有,则对其进行调试(通过使用调试器单步执行)。如果您遇到困难,请在此处发布特定问题以及您在调试时看到的详细信息。

标签: assembly while-loop arm keil


【解决方案1】:

code review questions aren't really on topic here,但我们有时会为 asm 设置例外。

如果有任何反馈,我将不胜感激。

Asm 循环通常应该看起来像 C do { } while( condition )

通常最好将条件分支放在循环的底部,这样就不需要单独的无条件分支。 (特别是当已知循环至少运行一次时,因此您不需要在第一次迭代之前进行检查或跳转到条件。)

在你的情况下,那将是

                    @ do{
    ...
add r0, #1
cmp r0, #10
bne Loop            @ } while(r0 != 10)

或者从 r0 = 10 开始,使用subs r0, #1 减去和设置标志,这样就不需要单独的cmp 指令了。


   TST R0, #1
   ADDEQ R1, #1

工作正常。您也可以无条件地添加低位,而不是有条件地添加 0 或 1。

   AND   R3, R0, #1
   ADD   R1, R3

如果您处于 Thumb2 模式,这将需要额外的 MOV 指令来非破坏性地提取低位,因为您不会有 3 操作数 AND。还是会?您可以使用位移来清除所有其他位,IIRC Thumb2 仍然允许将位移作为寄存器操作数的一部分。

   MOV   R3, R0 LSL #31    @  I think this is legal syntax
   ADD   R1, R3 LSR #31

MOV R3, R0 MOD 3

这看起来真的很狡猾。这甚至会组装吗?很确定 ARM 只能移动和旋转。 Mod 3 是一个非常昂贵的计算。

您应该改为使用从 3 开始倒数并在达到零时重置为 3 的递减计数器。您可以使用 ARM 条件/谓词执行来执行此操作和条件添加。

SUBS  R3, #1
MOVEQ R3, #3
ADDEQ R2, #1

【讨论】:

    猜你喜欢
    • 2012-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多