1

我根本没有编写汇编的经验,所以我猜这个问题很容易回答。

有这个简单的循环:

mov r0,#3
loop:
   do some instructions
   ...
   last-instruction

subs r0,r0,#1
bne loop
afterloop:

如果我理解得很好,这个循环应该从 3 减少到 0 并停止(如果我错了,请纠正我)。

但是,在最后一次迭代中,当 r0 == 0 时,我想跳过last-instruction并跳出循环。我认为cmp如果 r0 等于 0 然后跳转到afterloop. 但我想可能有一些更简单的方法来实现这一点。

编辑: 还有一个问题——如果要跳过更多指令怎么办?

在 C 中,它看起来像这样:

int i = 3;
while (1) {
  foo();

  if (i == 0) break;
  skipped_func();
  --i;
}
4

1 回答 1

4

除非最后一条指令依赖于 r0 和/或修改 CPSR,否则将subs行移动到最后一条指令的前一步,并使最后一条指令以 NE 条件为条件。像这样:

mov r0,#3
loop:
   do some instructions
   ...


    subs r0,r0,#1
    last-instructionNE
bne loop
afterloop:

如果最后一条指令是 a mov,则将其设为 a movne。如果是str,则将其设为strne。等等。

如果最后一条指令已经有一个“s”后缀,这将不起作用 - 修改标志。如果是这样,它将破坏零标志并且bne不会按预期工作。此外,如果最后一条指令依赖于 r0 在减少之前的值,它也必须在subs.

在 ARM 上,与 Intel 不同,几乎每条指令都可以是有条件的,而不仅仅是 B(ranch)。除非它实际上是拇指。

编辑重新:编辑:您可以通过这种方式使多个指令有条件。或者,您也可以通过跳转复制相同的逻辑。像这样:

mov r0,#3
loop:
   do some instructions
   ...
    subs r0,r0,#1
    bz afterloop

   last-instructions
b loop
afterloop:

这绝对是“智能”的组装方式。有人声称它更容易理解。对于 2-3 条条件行,我不会打扰。10+,我会的。中间有一个灰色区域。:)

Bz并且be是同义词。这样逻辑就更清楚了——你隐含地将 r0 与 0 进行比较。

在这种情况下,最后的指令可能会破坏他们想要的所有标志。从 r0 读取仍然会给你已经减少的值。

于 2013-03-18T21:24:14.113 回答