Почему это не изменит значения некоторых элементов в массиве 1 в памяти?

#assembly #arm #arm7

#сборка #arm #arm7

Вопрос:

Я написал некоторый ассемблерный код на Keil, где, если элемент в массиве равен < 5, программа увеличивает этот элемент. Проблема в том, что код ARM не изменяет значения массива 1 в памяти. Какие изменения мне нужно внести, чтобы сделать это?

     ADR r0, array1      ; loads address of 'a' to r0

    MOV r1, #0          ; r1 = index

L0  CMP r1, #8
    BGE stop
    LDR r2, [r0, r1, LSL#2] ; load content of array1[index] to r2
    CMP r2, #5
    ADDLT   r2, r2, #1      ; array1[index]  
    STRLT   r2, [r0, r1, LSL#2] ; store r2 as content of array1[index]
    ADD r1, r1, #1      ; index  
    B   L0

stop B  stop
array1  DCD 1, 7, 4, 9, 2, 3, 8, 6
    END
  

Комментарии:

1.Я предполагаю, что addlt также обновляет регистр флага, поэтому strlt больше не находится в состоянии «меньше» и не выполняется. Не могу вспомнить детали ARM, чтобы быть уверенным на 100%, но я думаю, что некоторые исключения о том, когда флаги обновления инструкций были скорее в режиме thumb? Что ж, обратитесь к своим руководствам или какому-нибудь симулятору / отладчику, что ваш addlt делает. Кстати, наличие отладчика и какого-нибудь симулятора / платы необходимо, чтобы вы могли сами проверить, каково состояние процессора перед strlt и почему оно не выполняется. … в случае, если это измененные флаги, вам нужно будет решить, хотите ли вы скорее разветвляться или сохранить каждый val.

2. Я не могу понять, почему это не сработает, поэтому мой вопрос — откуда вы знаете, что это не работает? Как вы проверяете память, какие инструменты вы используете?

3. @Ped7g addlt не должен устанавливать никаких флагов. Это было бы addslt вместо этого.

4. @fuz тогда я ошибаюсь и согласен с tum … на первый взгляд это должно хорошо работать, т. Е. нужно отладить это, чтобы увидеть, что на самом деле происходит.

5. Если вы новичок в сборке, попробуйте немного сместить свой мыслительный процесс в сторону физического отображения объектов. HW очень физический, и при написании кода на ассемблере вам часто приходится осознавать, где будет размещен ваш код, сколько места он занимает и какие ресурсы он использует. Многого из этого можно избежать в языках более высокого уровня, поскольку они держат вас за руку и создают вокруг вас своего рода «абстрактную» атмосферу, в то время как в сборке вы работаете непосредственно с предоставленным HW, как есть.

Ответ №1:

Ниже приведена карта памяти для Cortex-M3 DesignStart Eval. Конечно, это Cortex-M, а не ATM7TDMI, но он хорош в качестве примера.

Здесь вы можете увидеть область флэш-памяти, различные области расширения, периферийные устройства и различные типы оперативной памяти. Вы можете сравнить это с картой памяти LPC2140, чтобы проверить соответствующие адреса для вашего устройства.

Как правило, для программного кода области FLASH доступны только для чтения (для изменения FLASH требуется специальная последовательность управления, специфичная для фактической части). Области, отмеченные как расширение на этой диаграмме, не имеют ничего. Обращения к ним должны приводить к сбоям (с идеалистической точки зрения), но также могут просто игнорироваться. В DesignStart это области, в которые разработчики могут добавлять свое собственное оборудование. Единственная область, которую ваш код может надежно использовать для чтения / записи, — это области оперативной памяти. ARM-7 не имеет четко определенной карты памяти ARMv7-M, но для устройства LPC2140 вы можете быть уверены, что есть оперативная память между 0x40000000 и 0x40001FFF (а также флэш-память, начинающаяся с 0x00000000).

Архитектура ARM позволяет использовать область кода в качестве данных (таким образом, литералы могут быть встроены в код и доступны точно так же, как переменные). Это не гарантирует, что память кода может быть изменена.

Рис. 4-1 из ARM100894_0000_00_en

Рис. 4-1 из ARM100894_0000_00_en