В первую очередь, я не уверен, существует ли решение даже. Я провел больше чем несколько часов, пытаясь придумать один, поэтому остерегайтесь.
r1 содержит произвольное целое число, флаги не установлены согласно его значению. Набор r0 к 1, если r1 является 0x80000000, к 0 иначе, с помощью только двух инструкций.
Легко сделать это в 3 инструкциях (существует много путей), однако делание его в 2 кажется очень трудным, и может быть невозможным.
Вот частичное решение, которое дает правильный ответ в старшем бите r0
, поэтому оно доступно как операнд сдвига ( r0 lsr # 31
).
; r0 = r1 & -r1
rsb r0, r1, #0
and r0, r0, r1
Это работает, потому что 0
и 0x80000000
- единственные числа, которые сохраняют свои биты знака при отрицании. Я почти уверен, что точное решение невозможно.
РЕДАКТИРОВАТЬ: нет, это не невозможно. См. Ответ Мартина.
Сложная головоломка, если кто-то хочет использовать «быстрые» инструкции. Я не могу придумать решение, но могу предложить еще пару «идей»:
; 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
Ни одно из них не является идеальным решением, но они интересны.