Вопрос или проблема
Я новичок в разработке на ARM и мне нужно разобраться во многих вещах, но мне нужно завершить эту задачу. Чтобы резюмировать проблему, у меня есть неупорядоченный массив: (значения представляют собой <День, значение>, так что позиция 0 и позиция 1 идут “вместе”)
Failed_runs DCD 0x02, 50, 0x05, 30, 0x06, 100, 0x01, 58
DCD 0x03, 40, 0x04, 90, 0x07, 25
Мне нужен упорядоченный вариант этого массива на основе значений в порядке убывания и нужно сохранить день во втором массиве значений. Ожидаемое значение выглядит примерно так:
Failed_runs_ordered DCD 0x06, 0x04, 0x01, 0x02, 0x03, 0x05, 0x07
Я написала этот код и реализовала сортировку пузырьком, чтобы получить упорядоченный массив, но не могу понять, правильно ли были упорядочены мои данные. Я пыталась сохранить это в регистре, как показано в коде, но когда я выполняю цикл, я получаю странные значения, такие как ошибка сегментации памяти или память пуста.
код:
AREA |.text|, CODE, READONLY , ALIGN=2
; ГРАНИЦА
SPACE 4096
Days DCB 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
SPACE 4096
Best_times DCD 0x06, 1300, 0x03, 1700, 0x02, 1200, 0x04, 1900
DCD 0x05, 1110, 0x01, 1670, 0x07, 1000
SPACE 4096
Failed_runs DCD 0x02, 50, 0x05, 30, 0x06, 100, 0x01, 58
DCD 0x03, 40, 0x04, 90, 0x07, 25
Best_times_ordered SPACE 32
Failed_runs_ordered SPACE 32
SPACE 4096
Num_days DCB 0x07
; Обработчик сброса
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
LDR R1, =Best_times
LDR R0, =Failed_runs ; Точка начала массива Failed_runs
LDR R6, =Failed_runs_ordered
LDRB R2, Num_days ; Загружается число дней (7)
outer_loop
MOV R8, #0 ; Инициализация внутреннего индекса
MOV R11, #0
inner_loop
LDR R3, [R0, R8, LSL #2] ; R3 = текущий день
ADD R8, R8, #1 ; Увеличить на 2, чтобы перейти к следующему элементу
LDR R4, [R0, R8, LSL #2] ; R4 = текущее значение
SUB R8, R8, #1 ; Вернуться назад (восстановить R8)
ADD R9, R8, #2 ; Вычислить индекс для следующего дня
LDR R5, [R0, R9, LSL #2] ; R5 = следующий день
ADD R9, R9, #1 ; Увеличить R9 для загрузки следующего значения
LDR R7, [R0, R9, LSL #2] ; R6 = следующее значение
SUB R9, R9, #1 ; Вернуться назад
CMP R4, R6
BGE no_swap ; Если R4 >= R6, не делать обмена
swap_elements
STR R5, [R0, R8, LSL #2] ; Записать следующий день в текущее положение
ADD R8, R8, #1 ; Увеличить, чтобы записать значение
STR R7, [R0, R8, LSL #2] ; Записать следующее значение
SUB R8, R8, #1 ; Вернуться назад
STR R3, [R0, R9, LSL #2] ; Записать текущий день в следующее положение
ADD R9, R9, #1 ; Увеличить, чтобы записать значение
STR R4, [R0, R9, LSL #2] ; Записать текущее значение
SUB R9, R9, #1 ; Вернуться назад
no_swap
STR R3, [R7, R8, LSL #2]
ADD R11,R11,#1; Записать текущий день в Failed_runs_ordered
STR R5, [R7, R8, LSL #2]
ADD R8, R8, #2 ; Перейти к следующей паре
CMP R8, #12
BLT inner_loop ; Продолжать до завершения прохода
SUBS R2, R2, #1
BNE outer_loop ; Продолжать до тех пор, пока все не будет упорядочено
MOV R8, #0
check LDR R3, [R7, R8, LSL #2] ; R3 = текущий день
ADD R8, R8, #1
CMP R8, #12
BLT check
Я не понимаю, как правильно сохранить переменную или есть ли какие-либо другие ошибки?
Спасибо, и если что-то необходимо, дайте знать, и я добавлю.
Ответ или решение
Сортировка массива и хранение в ARM
ARM-разработка может быть сложной задачей для новичков, особенно при работе с низкоуровневыми данными и манипуляциями с памятью. Ваша задача заключается в сортировке неупорядоченного массива Failed_runs
, где каждые две позиции представляют собой пару значений: день и значение. Мы будем использовать алгоритм сортировки пузырьком для достижения этого.
Описание исходных данных
Исходный массив Failed_runs
представлен в формате:
Failed_runs DCD 0x02, 50, 0x05, 30, 0x06, 100, 0x01, 58
DCD 0x03, 40, 0x04, 90, 0x07, 25
Где, к примеру, 0x02
соответствует дню 2, а 50
— значению. Вы хотите их отсортировать по значению в порядке убывания и сохранить дни в окружающем массиве.
Структура программы
Программа должна включать выделение памяти для отсортированного массива и правильное использование регистров для манипуляции данными. Обратите внимание на выделение участков памяти и инициализацию массивов.
Исправленный код
Предлагаю вам более оптимизированный и исправленный код для выполнения этой задачи:
AREA |.text|, CODE, READONLY , ALIGN=2
Failed_runs DCD 0x02, 50, 0x05, 30, 0x06, 100, 0x01, 58
DCD 0x03, 40, 0x04, 90, 0x07, 25
Failed_runs_ordered SPACE 32
Num_days DCB 0x07
; Reset Handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
LDR R0, =Failed_runs ; Указатель на массив Failed_runs
LDR R1, =Failed_runs_ordered ; Указатель на массив Ordered
LDRB R2, Num_days ; Количество дней (7)
MOV R8, #0 ; Индекс внешнего цикла
outer_loop
MOV R9, #0 ; Индекс внутреннего цикла
inner_loop
CMP R9, #12 ; Проверка конца массива
BGE end_inner_loop ; Если конец, выход
LDR R3, [R0, R9, LSL #2] ; Текущий день
LDR R4, [R0, R9, LSL #2 + 4] ; Текущее значение
ADD R10, R9, #2 ; Индекс следующей пары
LDR R5, [R0, R10, LSL #2] ; Следующий день
LDR R6, [R0, R10, LSL #2 + 4] ; Следующее значение
; Проверка на сортировку по убыванию
CMP R4, R6
BGE no_swap ; Если текущее значение больше или равно следующему, прыгнуть
; Работа с обменом значений
STR R5, [R0, R9, LSL #2] ; Поменять дни
STR R6, [R0, R9, LSL #2 + 4] ; Поменять значения
STR R3, [R0, R10, LSL #2] ; Поменять дни
STR R4, [R0, R10, LSL #2 + 4] ; Поменять значения
no_swap
ADD R9, R9, #2 ; Следующий индекс
B inner_loop ; Продолжить внутренний цикл
end_inner_loop
ADD R8, R8, #1 ; Следующий проход
CMP R8, R2 ; Проверка на полный проход
BLT outer_loop ; Если не все отсортировано, вернуться к внешнему циклу
; Копирование отсортированных значений в отсортированный массив
MOV R8, #0
copy_loop
CMP R8, #12
BGE end_copy
LDR R3, [R0, R8, LSL #2]
STR R3, [R1, R8, LSL #2]
ADD R8, R8, #2
B copy_loop
end_copy
BX LR ; Возврат из процедуры
Описание изменений
-
Упрощение логики сортировки: Сохраняя вашу структуру, я улучшил логику внутреннего цикла, чтобы избежать лишних операций.
-
Использование эффективного копирования данных: В конце сортировки добавлен цикл для копирования отсортированных данных в новый массив.
-
Корректная работа с регистрами: Каждое значение загружается и сохраняется из нужного места, избегая возможных ошибок сегментации памяти.
Заключение
Работа с ARM Assembly требует тщательности и внимательности к деталям. Убедитесь, что ваша среда разработки корректно настроена, и внимательно следите за регистрами и адресами памяти. Протестируйте фрагмент кода и внесите необходимые изменения, если возникнут дополнительные сложности.