ARM程序集中的跳过指令

时间:2013-03-18 21:18:44

标签: assembly arm

我根本没有写过大会的经验,所以我觉得这个问题很容易回答。

有这个简单的循环:

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

subs r0,r0,#1
bne loop
afterloop:

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

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

修改 还有一个问题 - 如果有更多指令要跳过怎么办?

在C中它看起来像这样:

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

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

1 个答案:

答案 0 :(得分:4)

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

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


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

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

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

在ARM上,与英特尔不同,几乎每条指令都可以成为条件,而不仅仅是B(牧场)。除非它实际上是拇指。

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

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

   last-instructions
b loop
afterloop:

这绝对是“英语”式的装配风格。有些人声称它更容易理解。对于2-3条条件行,我不会打扰。对于10岁以上,我愿意。在中间有一个灰色区域。 :)

Bzbe是同义词。这种逻辑更清晰 - 你隐含地将r0与0进行比较。

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