简体   繁体   中英

Manipulating an array in memory via the arm c inline assembler

int smplSize = 48;
int Smpl[48];

for(int i = 0; i < smplSize; i++) Smpl[i] = 0x0;
Smpl[smplSize-1] = 0x1;

int *ptrToSmpl = &Smpl[0];

printf("Sample @%p of Size %i :\n",(void*)ptrToSmpl,smplSize);

asm volatile(

             "@ ------------------------------------------------- \n"
             "@ Invert the sample \n"
             "@ ------------------------------------------------- \n"

            //"0:                \n"
            "ldr r2,[r3] \n"
            //"cmp r2,#0x1          \n"
            //"bne 1f             \n"
            "add r2,#0x1       \n"

            //"add r2,#0x1          \n"
            "str r2,[r3]        \n"

            //"ldr r1, .0             \n"
            //"bx  r1             \n"
            //"1:                \n"


            :
            : "r"   (ptrToSmpl)
            : "r3", "memory"

             );

printf("Sample[0] = %i" , Smpl[0]);

Edit:

As you can see I want to manipulate a variable of an array via the inline assembler on arm, but I always get a segfault. How can I access the memory without segfault?

printf("Hello inline asmTest start!\n\n");

int smplSize = 48;
int Smpl[48];

for(int i = 0; i < smplSize; i++) Smpl[i] = 0x0;
Smpl[smplSize-1] = 0x1;

int *ptrToSmpl = &Smpl[0];

printf("Sample @%p of Size %i :\n",(void*)ptrToSmpl,smplSize);

asm volatile(

             "@ ------------------------------------------------- \n"
             "@ Invert the sample \n"
             "@ ------------------------------------------------- \n"

            //"0:                \n"

            "ldr r2,%[ptrToSmpl] \n"
            //"cmp r2,#0x1          \n"
            //"bne 1f             \n"
            "add r2,#0x1       \n"

            //"add r2,#0x1          \n"
            "str r2,%[ptrToSmpl]        \n"

            //"ldr r1, .0             \n"
            //"bx  r1             \n"
            //"1:                \n"


            :
            : [ptrToSmpl]"r"   (ptrToSmpl)
            :

             );

printf("Sample[0] = %i" , Smpl[0]);

Ok, I did so, but now I get a "/tmp/cczQDyiw.s|72|Error: internal_relocation (type: OFFSET_IMM) not fixed up|" when compiling it.

BTW: Can I "org [Adress of the programm]" the inline asm code ?

printf("Hello inline asmTest start!\n\n");

int smplSize = 48;
int Smpl[48];

for(int i = 0; i < smplSize; i++) Smpl[i] = 0x0;
Smpl[smplSize-1] = 0x1;

int *ptrToSmpl = &Smpl[0];

printf("Sample @%p of Size %i :\n",(void*)ptrToSmpl,smplSize);

asm volatile(

             "@ ------------------------------------------------- \n"
             "@ Invert the sample \n"
             "@ ------------------------------------------------- \n"

            "init:                \n"
            "ldr   r0,%[ptrToSmpl] \n"

            "loop :                 \n"
            "ldr r4,[r0]        \n"
            "cmp r4,#0x0          \n"
            "bne  end             \n"

            "add r4,#0x1          \n"
            "str r4,[r0]        \n"

            "add r0,#0x1       \n"


            "b  loop             \n"
            "end:                \n"


            :
            : [ptrToSmpl]"r"   (ptrToSmpl)
            :  "r0" , "r4", "memory"

             );

printf("Sample[0] = %i" , Smpl[0]);

Edit 2:

As you can see above theres still a bug in the adressing I think. The error message now is: "/tmp/ccE69oZd.s|75|Error: undefined symbol r6 used as an immediate value|" but there's no r6 anywhere.

Don't hard code the registers that the assembly is supposed to use. Use the %0 , %1 etc notation to name the registers that correspond to the parameters that you are passing.

If you do so correctly you shouldn't need to use constraints such as "memory" in your case.

You should put %[ptrToSmpl] inside square brackets - you want to load/store from/to the address that is in the register.

This ldr r2,%[ptrToSmpl] gets translated into ldr r2,rX - nonsense

This ldr r2,[%[ptrToSmpl]] ldr r2,[rX] - correct

Moreover - you should put r2 into the list of clobbered registers, as you overwrite what compiler puts there. Add "r2" (with quotes) after the last (third) colon.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM