Пазл ARM сборки - PullRequest
       37

Пазл ARM сборки

9 голосов
/ 02 июня 2010

Прежде всего, я не уверен, что решение вообще существует. Я потратил больше пары часов, пытаясь придумать один, так что будьте осторожны.

Проблема:

r1 содержит произвольное целое число, флаги не установлены в соответствии с его значением. Установите r0 в 1, если r1 - 0x80000000, в противном случае - в 0, используя только две инструкции.

Это легко сделать в 3 инструкциях (есть много способов), однако выполнить это в 2 кажется очень трудным и вполне может быть невозможным.

Ответы [ 5 ]

6 голосов
/ 05 июня 2010

что-то вроде

SMMUL r0,r1,r1
MOV r0,r0,lsr #30
3 голосов
/ 04 июня 2010

Вот частичное решение, которое дает правильный ответ в верхнем бите r0, поэтому оно доступно в качестве операнда сдвига (r0 lsr #31).

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

Это работает, потому что 0 и 0x80000000 являются единственными числами, которые сохраняют свои знаковые биты при отрицании. Я вполне уверен, что точное решение невозможно.

РЕДАКТИРОВАТЬ: нет, это не невозможно. Смотрите ответ Мартина.

1 голос
/ 21 марта 2011
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;
}
0 голосов
/ 01 июля 2010

Сложная головоломка, если кто-то хочет использовать «быстрые» инструкции. Я не могу придумать решение, но могу предложить еще пару «понятий»:

; 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

Ни одно из них не является идеальным решением, но они интересны.

0 голосов
/ 03 июня 2010

Что-то вроде:

mov r0, r1, lsr # 31

...