Сборка ARM: регистр автоинкремента в хранилище

Можно ли автоматически увеличивать базовый адрес регистра в STR с помощью [ Rn]! ? Я просмотрел документацию, но не смог найти окончательного ответа, в основном потому, что синтаксис команды представлен как для LDR, так и для STR - теоретически он должен работать для обоих, но я не мог не нашел примеров автоинкремента в магазине (загрузка работает нормально).

Я сделал небольшую программу, которая хранит два числа в векторе. Когда это сделано, содержимое out должно быть {1, 2} , но хранилище перезаписывает первый байт, как будто автоинкремент не работает.

#include <stdio.h>

int main()
{
        int out[]={0, 0};
        asm volatile (
        "mov    r0, #1          \n\t"
        "str    r0, [%0]!       \n\t"
        "add    r0, r0, #1      \n\t"
        "str    r0, [%0]        \n\t"
        :: "r"(out)
        : "r0" );
        printf("%d %d\n", out[0], out[1]);
        return 0;
}

РЕДАКТИРОВАТЬ: Хотя ответ был правильным для обычных загрузок и сохранений, я обнаружил, что оптимизатор портит автоинкремент для векторных инструкций, таких как vldm / vstm.Например, следующая программа

#include <stdio.h>

int main()
{
        volatile int *in = new int[16];
        volatile int *out = new int[16];

        for (int i=0;i<16;i++) in[i] = i;

        asm volatile (
        "vldm   %0!, {d0-d3}            \n\t"
        "vldm   %0,  {d4-d7}            \n\t"
        "vstm   %1!, {d0-d3}            \n\t"
        "vstm   %1,  {d4-d7}            \n\t"
        :: "r"(in), "r"(out)
        : "memory" );

        for (int i=0;i<16;i++) printf("%d\n", out[i]);
        return 0;
}

, скомпилированная с помощью

g++ -O2 -march=armv7-a -mfpu=neon main.cpp -o main

, будет выдавать тарабарщину на выходе последних 8 переменных, потому что оптимизатор сохраняет увеличенную переменную и использует ее для printf. Другими словами, out [i] на самом деле out [i + 8] , поэтому первые 8 выводимых значений - это последние 8 из вектора, а остальные - области памяти вне границы.

Я пробовал использовать различные комбинации ключевого слова volatile во всем коде, но поведение меняется только при компиляции с флагом -O0 или если я использую изменчивый вектор вместо указателя и новый, например

volatile int out[16];
6
задан John S 7 February 2012 в 11:41
поделиться