ARM组装难题

时间:2010-06-02 18:46:41

标签: assembly arm bit-manipulation puzzle

首先,我不确定解决方案是否存在。我花了不少时间试图想出一个,所以要小心。

问题:

r1包含一个任意整数,标志根据其值设置。如果r1为0x80000000,则将r0设置为1;否则,仅使用两条指令将r0设置为

在3条指令中很容易做到这一点(有很多种方法),但是在2中这样做似乎很难,而且很可能是不可能的。

5 个答案:

答案 0 :(得分:6)

类似

SMMUL r0,r1,r1
MOV r0,r0,lsr #30

答案 1 :(得分:3)

这是一个部分解决方案,可以在r0的最高位给出正确答案,因此它可用作移位器操作数(r0 lsr #31)。

; r0 = r1 & -r1
rsb r0, r1, #0
and r0, r0, r1

这是有效的,因为00x80000000是唯一在被否定时保留其符号位的数字。我很确定一个确切的解决方案是不可能的。

编辑:不,这不是不可能的。见马丁的答案。

答案 2 :(得分:1)

adds  r0, r1, #0x80000000 ; if r1 is 0x80000000, r0 will now hold 0
movne r0, #1              ; otherwise, set r0 to 1

这相当于:

unsigned int r0, r1;
r0 = r1 + 0x80000000; // 32 bits, so top bit will be lost on overflow
if (r0 != 0)
{
    r0 = 1;
}

答案 3 :(得分:0)

类似的东西:

mov r0,r1,lsr#31

答案 4 :(得分:0)

如果想要使用“快速”指令,那就是难题。我无法提出解决方案,但可以提供更多“概念”:

; If goal were to have value of zero if $80000000 and something else otherwise:
  adds r0,r1,r1 ; Overflow only if $80000000
  movvc r0,#whatever

; If goal were to have value of $80000000 if $80000000 and zero otherwise
  subs r0,r1,#0  ; Overflow only if $80000000
  movvc r0,#0 ; Or whatever

; If the goal were to have value of $7FFFFFFF if $80000000 and zero otherwise
  adds r0,r1,r1,asr #31 ; Overflow only if $80000000
  movvc r0,#0

; If carry were known to be set beforehand
  addcs r0,r1,r1 ; Overflow only if $80000000 (value is 1)
  movvc r0,#0

; If register r2 were known to hold #1
  adds r0,r1,r1,asr #31
  ; If $80000000, MSB and carry set
  sbc r0,r2,r0,lsr #31

这些都不是一个完美的解决方案,但它们很有趣。