#assembly #keil #cortex-m
#сборка #keil #cortex-m
Вопрос:
Допустим, я загружаю 3 числовых значения в три разных регистра. И я хочу найти среднее число.
AREA median, CODE, READONLY
EXPORT main
first EQU 3
middle EQU 3
last EQU 9
ENTRY
main
MOV R0, #first
MOV R1, #middle
MOV R2, #last
----------
Here i would like to compare these 3 values and find the middle number. (in this case, 3)
Я пробовал что-то вроде CMP R1, R2
, но мне не удалось сохранить значение, которое я хотел, в регистре. Это то, что я пытался найти, меньшее или большее из двух.
main:
mov r1, #3 /* setting up initial variable a */
mov r2, #9 /* setting up initial variable b */
cmp r1, r2 /* comparing variables to determine which is bigger */
blt r1_lower /* jump to r1_lower in case r2 is bigger */
mov r0, r1 /* if branching/jumping did not occur, r1 is bigger (or the same) so store r1 into r0 */
b end /* proceed to the end */
r1_lower:
mov r0, r2 /* end up here because r1 was smaller than r2, so move r2 into r0 */
b end /* proceed to the end */
Есть мысли?
Комментарии:
1. Каково начальное значение
r0
?2. @fuz Начальное значение r0 равно 0x00
3. Для алгоритма, я думаю, вам нужно 3 сравнения. Для получения минимального или максимального значения требуется всего 2, но вы не можете исключить любое значение в качестве возможного среднего после первого сравнения.
Ответ №1:
Конкретно для трех чисел существует два основных подхода:
-
вы можете отсортировать три числа и вернуть среднее число из отсортированного массива. Для этого обычно полезна трехступенчатая сеть сортировки. Для сборки этого используйте этот примитив, который меняет местами
r0
иr1
, еслиr0
больше, чемr1
, используяr3
в качестве временного регистра:cmp r0, r1 # if (r0 > r1) movgt r3, r1 # r2 = r1 movgt r1, r0 # r1 = r0 movgt r0, r3 # r0 = r1
-
в качестве альтернативы вы можете вычислить максимальное и минимальное из трех чисел и вычесть его из их суммы, получив среднее число. Например, если три числа находятся в
r0
,r1
иr2
, это может быть сделано с помощью:cmp r0, r1 # if (r0 > r1) movgt r3, r0 # then r3 = r0 (r3 is max) movgt r4, r1 # then r4 = r1 (r4 is min) movle r3, r1 # else r3 = r1 movle r4, r0 # else r4 = r0 cmp r2, r3 # if (r2 > r3) movgt r3, r2 # then r3 = r2 cmp r4, r2 # if (r4 > r2) movgt r4, r2 # then r4 = r2 add r5, r0, r1 # r5 = r0 r1 (r5 is middle) add r5, r5, r2 # r5 = r5 r2 sub r5, r5, r3 # r5 = r5 - r3 sub r5, r5, r4 # r5 = r5 - r5
Ответ №2:
С какой именно проблемой вы столкнулись? Ваша CMP
инструкция в порядке и установит флаги состояния в зависимости от относительных значений R0
и R1
, поэтому затем вы можете использовать условную ветвь (например, BHI
or BGT
) или одну из IT
семейства инструкций, которая позволит вам выполнять другие инструкции условно, используя те же коды условий.
Здесь есть краткий справочник по набору команд Thumb-2 (используемому большинством устройств Cortex-M, которые, как я предполагаю, вы используете в отсутствие какой-либо другой информации), а также множество дополнительной документации по условному ветвлению и условному выполнению на сайте ARM Infocenter, например, здесь для Cortex-M3.