Как правило, вы смотрите на допустимый диапазон значений.
- Убедитесь, что значение находится в диапазоне.
- Вычтите наименьшее значение из регистра.
- Использовать измененное значение в качестве индекса массива; Массив может иметь ключ значения или просто быть да/нет.
Шаги 2,3 необходимы только в том случае, если некоторые значения в диапазоне недействительны, и массив должен быть достаточно плотно упакован, что должно иметь место для вашего двузначного шестнадцатеричного числа.
# Range check (step 1)
cmp r2, #hi_val
bhi out_of_range
cmp r2, #low_val ; optimized version is subs r2, r2, #low_val
blo out_of_range
# Adjust value (step 2)
sub r2, r2, #low_val ; removed in optimized version.
# Get check from array (step 3)
adr r0, key_array
ldrb r0, [r0, r2] ; base of array + adjusted value.
bx lr ; return w. result in r0.
# Handle not in range.
out_of_range:
mov r0, #-1
bx lr ; use 0xffffffff for out of range.
# This is a constant array included with the code.
key_array:
.byte 1, 1, 0, 1, 1, 1, 0, 0, 1, 1 # etc.
Очевидно, что ваш key_array
должен быть изменен, чтобы соответствовать вашему варианту использования. Коды условий немного изменятся для значений со знаком и без знака.
Если key_array
- это все единицы для двоичного случая, то шаги два и три - это просто return 1;
. Если low_val
равно нулю, вам не нужно вычитать (или выполнять проверку низкого диапазона). Размер key_array
должен быть hi_val - low_val + 1
, иначе логика проверки диапазона может измениться.
Этот механизм используется для многих функций «ctype», таких как ispunct
, но вы можете хранить до восьми значений в байте и использовать битовую маску, чтобы получить то, что вас интересует. Его также легко реализовать на «C» и используйте компилятор. Можно использовать только один регистр (R0 является функцией, совместимой с EABI), но тогда обработка ошибок также будет смешанной и менее понятной.
person
artless noise
schedule
06.01.2017