通过arm c内联汇编程序在内存中操作数组

时间:2014-09-26 11:44:40

标签: c gcc assembly arm inline-assembly

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]);

编辑:

正如你所看到的,我想通过arm上的内联汇编程序来操作数组的变量,但我总是得到段错误。如何在没有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]);

好的,我这样做了,但现在我得到一个“/tmp/cczQDyiw.s|72|错误:internal_relocation(类型:OFFSET_IMM)未修复”编译时。

顺便说一句:我可以“组织[编程的地址]”内联asm代码吗?

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]);

编辑2:

正如你在上面所看到的那样,我认为仍然存在一个错误。 现在的错误消息是: “/tmp/ccE69oZd.s|75|Error:未定义的符号r6用作立即值|” 但是在任何地方都没有r6。

2 个答案:

答案 0 :(得分:1)

不要硬编码程序集应该使用的寄存器。使用%0%1等表示法命名与您传递的参数对应的寄存器。

如果您正确执行此操作,则不需要在案例中使用"memory"等约束。

答案 1 :(得分:1)

您应该将%[ptrToSmpl]放在方括号内 - 您希望从/向寄存器中的地址加载/存储。

ldr r2,%[ptrToSmpl]被翻译为ldr r2,rX - 废话

ldr r2,[%[ptrToSmpl]] ldr r2,[rX] - 正确

此外 - 你应该将r2放入被破坏的寄存器列表中,因为你覆盖了编译器放在那里的东西。添加&#34; r2&#34; (带引号)在最后一个(第三个)冒号之后。