Сохранить упорядоченный массив в памяти/регистре – ARM

Вопрос или проблема

Я новичок в разработке на 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                     ; Возврат из процедуры

Описание изменений

  1. Упрощение логики сортировки: Сохраняя вашу структуру, я улучшил логику внутреннего цикла, чтобы избежать лишних операций.

  2. Использование эффективного копирования данных: В конце сортировки добавлен цикл для копирования отсортированных данных в новый массив.

  3. Корректная работа с регистрами: Каждое значение загружается и сохраняется из нужного места, избегая возможных ошибок сегментации памяти.

Заключение

Работа с ARM Assembly требует тщательности и внимательности к деталям. Убедитесь, что ваша среда разработки корректно настроена, и внимательно следите за регистрами и адресами памяти. Протестируйте фрагмент кода и внесите необходимые изменения, если возникнут дополнительные сложности.

Оцените материал
Добавить комментарий

Капча загружается...