Для хранения и загрузки вы делаете это:
ldr r0,[r1],#4
str r0,[r2],#4
все, что вы ставите в конце, в данном случае 4, добавляется в базовый регистр (r1 в примере ldr и r2 в примере str) после того, как регистр используется для адреса, но до того, как инструкция завершена, она очень похоже на
unsigned int a,*b,*c;
...
a = *b++;
*c++ = a;
РЕДАКТИРОВАТЬ, вам нужно посмотреть на разборки, чтобы увидеть, что происходит, если что-нибудь. Я использую последний исходный код или просто исходный текст из инструментария наставника графики.
arm-none-linux-gnueabi-gcc (Sourcery CodeBench Lite 2011.09-70) 4.6.1
#include <stdio.h>
int main ()
{
int out[]={0, 0};
asm volatile (
"mov r0, #1 \n\t"
"str r0, [%0], #4 \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;
}
arm-none-linux-gnueabi-gcc str.c -O2 -o str.elf
arm-none-linux-gnueabi-objdump -D str.elf > str.list
00008380 <main>:
8380: e92d4010 push {r4, lr}
8384: e3a04000 mov r4, #0
8388: e24dd008 sub sp, sp, #8
838c: e58d4000 str r4, [sp]
8390: e58d4004 str r4, [sp, #4]
8394: e1a0300d mov r3, sp
8398: e3a00001 mov r0, #1
839c: e4830004 str r0, [r3], #4
83a0: e2800001 add r0, r0, #1
83a4: e5830000 str r0, [r3]
83a8: e59f0014 ldr r0, [pc, #20] ; 83c4 <main+0x44>
83ac: e1a01004 mov r1, r4
83b0: e1a02004 mov r2, r4
83b4: ebffffe5 bl 8350 <_init+0x20>
83b8: e1a00004 mov r0, r4
83bc: e28dd008 add sp, sp, #8
83c0: e8bd8010 pop {r4, pc}
83c4: 0000854c andeq r8, r0, ip, asr #10
так что
sub sp, sp, #8
- выделить два локальных типа out [0] и out [1]
mov r4,#0
str r4,[sp]
str r4,[sp,#4]
потому что они инициализируются нулем, затем идет встроенная сборка
8398: e3a00001 mov r0, #1
839c: e4830004 str r0, [r3], #4
83a0: e2800001 add r0, r0, #1
83a4: e5830000 str r0, [r3]
и затем printf:
83a8: e59f0014 ldr r0, [pc, #20] ; 83c4 <main+0x44>
83ac: e1a01004 mov r1, r4
83b0: e1a02004 mov r2, r4
83b4: ebffffe5 bl 8350 <_init+0x20>
и теперь понятно, почему это не сработало. Вы не объявлены как изменчивые. Вы не дали коду никакой причины вернуться к ram, чтобы получить значения out [0] и out [1] для printf, компилятор знает, что r4 содержит значение как для out [0], так и для out [1]. в этой функции так мало кода, что ему не нужно было выселять r4 и использовать его повторно, поэтому он использовал r4 для printf.
Если вы измените его на изменчивый
volatile int out[]={0, 0};
Тогда вы должны получить желаемый результат:
83a8: e59f0014 ldr r0, [pc, #20] ; 83c4 <main+0x44>
83ac: e59d1000 ldr r1, [sp]
83b0: e59d2004 ldr r2, [sp, #4]
83b4: ebffffe5 bl 8350 <_init+0x20>
подготовка к printf читает из оперативной памяти.