2017-01-21 5 views
0

В моей процедуре сборки в какой-то момент мне нужно умножить два беззнаковых 32-битных целых числа и вернуть ошибку, если результат слишком велик, чтобы вписаться в 32-битное целое число.ARM - определение того, подходит ли результат умножения в 32 бит

Так я это сделать:

muls r3, r1, r2 @ r1, r2 
bcs multiply_error 

К сожалению, это не работает, как я ожидал, - я думал, что флаг переноса будет установлен, если результат слишком велик, но когда r1 = 1 и r2 = 1 , флаг переноса также установлен (почему?). Я также попытался проверить флаг переполнения - оказалось, что он не установлен вообще (по крайней мере, в тестах, которые я пробовал: r1 = 1, r2 = 1 и r1 = UINT_MAX, r2 = 2).

Как работают флаги в этом случае? Как проверить, если r1 * r2 соответствует 32-битным?

+1

Справочник по набору инструкций конкретно указывает: «Не влияет на флаг C или V». – Jester

+2

[Обнаружение переполнения из MUL] (https://community.arm.com/processors/b/blog/posts/detecting-overflow-from-mul) –

ответ

2

За документации ARM для MUL инструкции:

  • флаг C устанавливается в бессмысленном значение
  • флаг V неизменна

так что нет никакой помощи там. Вместо этого вам нужно использовать инструкцию UMULL (или SMULL, если вы хотите, чтобы она была подписана), которая умножает два 32-битных значения, генерирующих 64-разрядный результат в двух регистрах, а затем проверяет верхний регистр, если он отличен от нуля.

1

Если аппаратное обеспечение не поможет вам немного подумать о том, что вы уже знаете. число 4 является двоичным 0b100, которое равно нулю в два раза с мощностью 0 плюс ноль раз два с мощностью 1 плюс один раз два на мощность 2. Наш самый старший бит равен 2 мощности 2. умножьте это на 13, наиболее значимые бит равен 2 мощности 3. Поэтому имеем 2^2 * (2^3 + 2^2 + 2^0), который распределяет (2^2 * 2^3) + (2^2 * 2^2) и и так далее, наш самый значительный бит получается из (2^2 * 2^3), который с другим математическим свойством приходит к 2^(2 + 3) или 2^5. поэтому прямо сейчас нам нужно как минимум 6 бит, существует вероятность того, что msbit сложения, когда мы поставим все эти вещи вместе, переносится таким образом, что нам нужно 7 бит, чтобы умножить 3-битное число (наиболее значимое значение, отличное от нуля бит равен 2 на мощность 2) раз 4-битное число (msb равно 2 мощности 3). 3 + 4 = 7 бит. Для неподписанных, для подписанных вы должны учитывать наиболее значимые ноль или наиболее значимые, и т. Д. И т. Д.

или просто переходите с простым путем к любому 32-битовому шаблону, когда любой 32-разрядный шаблон требует 64-битного результата, чтобы не переполнение.

Что касается обнаружения для определенного набора команд, просто прочтите документацию поставщиков процессоров для этой инструкции.

 Смежные вопросы

  • Нет связанных вопросов^_^