【问题标题】:Manipulating an array in memory via the arm c inline assembler通过 arm c 内联汇编器操作内存中的数组
【发布时间】:2014-09-26 11:44:39
【问题描述】:
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 上的内联汇编器操作数组的变量,但我总是遇到段错误。如何在没有段错误的情况下访问内存?

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)未修复|”编译时。

顺便说一句:我可以“org [程序地址]”内联 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|错误:未定义的符号 r6 用作立即值|” 但是哪里都没有 r6。

【问题讨论】:

  • 如何确保 ptrToSmpl 以 r3 结尾? goo.gl/1aJ5t8
  • 如果您还有其他问题,请开始一个新的话题 - 一旦给出并接受了答案,您的编辑就很难跟进,也很难正确回答。顺便说一句 - 你使用 adr 的想法是完全错误的,这表明你不知道这条指令的作用......
  • sry 使用 adr 是一个错误,应该是 ldr。

标签: c gcc assembly arm inline-assembly


【解决方案1】:

您应该将%[ptrToSmpl] 放在方括号内 - 您想从/存储到寄存器中的地址。

这个ldr r2,%[ptrToSmpl] 被翻译成ldr r2,rX - 废话

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

此外-您应该将 r2 放入已破坏的寄存器列表中,因为您会覆盖编译器放在那里的内容。在最后一个(第三个)冒号后添加“r2”(带引号)。

【讨论】:

  • 如何增加ptr的值?
  • 只要观察你的编译器是怎么做的(;写一个简单的循环,看看它是如何转换成汇编的(你可以像这样arm-none-eabi-objdump --demangle -S file.elf &gt; file.lss生成汇编列表)。如果你想增加地址寄存器之后加载(或存储),你这样做ldr r1, [r2], #4(4显然是添加到r2的数字)。我建议你用C编写代码并检查程序集- 然后你会看到编译器的表现如何(并决定不自己编写),或者你会看到这些结构是如何被翻译成汇编的。
【解决方案2】:

不要对程序集应该使用的寄存器进行硬编码。使用%0%1 等符号来命名与您传递的参数相对应的寄存器。

如果你这样做正确,你应该不需要在你的情况下使用诸如"memory"之类的约束。

【讨论】:

    猜你喜欢
    • 2016-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多