简体   繁体   English

通过arm C内联汇编器在内存中处理数组

[英]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. 如您所见,我想通过arm上的内联汇编器来操作数组的变量,但是我总是遇到段错误。 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|" 好的,我这样做了,但是现在我得到一个“ /tmp/cczQDyiw.s | 72 |错误:内部定位(类型:OFFSET_IMM)未修复|” when compiling it. 编译时。

BTW: Can I "org [Adress of the programm]" the inline asm code ? 顺便说一句:我可以“组织[程序的地址]”内联的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]);

Edit 2: 编辑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|" 现在的错误消息是:“ / tmp / ccE69oZd.s | 75 |错误:未定义的符号r6用作立即值|” but there's no r6 anywhere. 但哪里都没有r6。

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. 使用%0%1等符号来命名与您要传递的参数相对应的寄存器。

If you do so correctly you shouldn't need to use constraints such as "memory" in your case. 如果正确执行此操作,则无需使用"memory"约束。

You should put %[ptrToSmpl] inside square brackets - you want to load/store from/to the address that is in the register. 您应该将%[ptrToSmpl]放在方括号内-您要从寄存器中的地址加载/存储。

This ldr r2,%[ptrToSmpl] gets translated into ldr r2,rX - nonsense 这个ldr r2,%[ptrToSmpl]被翻译成ldr r2,rX ldr r2,%[ptrToSmpl]废话

This ldr r2,[%[ptrToSmpl]] ldr r2,[rX] - correct 这个ldr r2,[%[ptrToSmpl]] ldr r2,[rX] -正确

Moreover - you should put r2 into the list of clobbered registers, as you overwrite what compiler puts there. 此外,在覆盖编译器放置的内容时,应将r2放入损坏的寄存器列表中。 Add "r2" (with quotes) after the last (third) colon. 在最后一个(第三个)冒号后面添加“ r2”(带引号)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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