首先,我不确定解决方案是否存在。我花了不少时间试图想出一个,所以要小心。
r1包含一个任意整数,标志不根据其值设置。如果r1为0x80000000,则将r0设置为1;否则,仅使用两条指令将r0设置为
在3条指令中很容易做到这一点(有很多种方法),但是在2中这样做似乎很难,而且很可能是不可能的。
答案 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
这是有效的,因为0
和0x80000000
是唯一在被否定时保留其符号位的数字。我很确定一个确切的解决方案是不可能的。
答案 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
这些都不是一个完美的解决方案,但它们很有趣。