我试图从下面的代码中删除堆栈依赖项。
void myfunction(struct kprobe *p, struct pt_regs *regs)
{
register void *rregs asm("r1") = regs;
register void *rfn asm("lr") = p->ainsn.insn_fn;
__asm__ __volatile__ (
"stmdb sp!, {%[regs], r11} \n\t"
"ldmia %[regs], {r0-r12} \n\t"
"blx %[fn] \n\t"
"ldr lr, [sp], #4 \n\t" /* lr = regs */
"stmia lr, {r0-r12} \n\t"
"ldr r11, [sp], #4 \n\t"
: [regs] "=r" (rregs), [fn] "=r" (rfn)
: "" (rregs), "1" (rfn)
: "r0", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r12", "memory", "cc"
);
}在上面的函数中,stmdb sp!, {%[regs], r11}将r1和r11推入堆栈中,然后再进行检索。
在我的例子中,我应该避免在这里使用堆栈。所以我重写了
void myfunction(struct kprobe *p, struct pt_regs *regs)
{
int r1_bk = 0, r11_bk = 0;
register void *rregs asm("r1") = regs;
register void *rfn asm("lr") = p->ainsn.insn_fn;
register void *r1b_c asm("r1") = &r1_bk;
register void *r11b_c asm("r11") = &r11_bk;
__asm__ __volatile__ (
"ldr %[r1b], r1 \n\t"
"ldr %[r11b], r11 \n\t"
"ldmia %[regs], {r0-r12} \n\t"
"blx %[fn] \n\t"
"ldr lr, %[r1b] \n\t" /* lr = regs */
"stmia lr, {r0-r12} \n\t"
"ldr r11, %[r11b] \n\t"
: [regs] "=r" (rregs), [fn] "=r" (rfn), [r1b] "=r" (r1b_c), [r11b] "=r" (r11b_c)
: "0" (rregs), "1" (rfn)
: "r0", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r12", "memory", "cc"
);
}当我编译时,下面的错误是我得到的。
/tmp/ccJMefdC.s: Assembler messages:
/tmp/ccJMefdC.s:579: Error: internal_relocation (type: OFFSET_IMM) not fixed up
/tmp/ccJMefdC.s:580: Error: internal_relocation (type: OFFSET_IMM) not fixed up
/tmp/ccJMefdC.s:583: Error: internal_relocation (type: OFFSET_IMM) not fixed up
/tmp/ccJMefdC.s:585: Error: internal_relocation (type: OFFSET_IMM) not fixed up我指的是这里,internal relocation not fixed up。但它并没有给出明确的想法。请分享你对此的认识。
发布于 2013-11-27 11:49:36
您的内联asm调用敲除器几乎所有寄存器,并且通过volatile指令显式地告诉编译器,它不应该跳过或试图移动调用以优化寄存器的使用。这意味着编译器在为myfunction生成等效指令时,需要在发出内联程序集之前将寄存器保存到某个位置。
让我向你证明:
$ cat asm_vol.c
void f() {
asm volatile("" : : : "r0", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r12", "memory", "cc");
}
$ arm-linux-gnueabihf-gcc -c -O2 asm_vol.c
$ arm-linux-gnueabihf-objdump -d asm_vol.o
asm_vol.o: file format elf32-littlearm
Disassembly of section .text:
00000000 <f>:
0: e92d 07f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl}
4: e8bd 07f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl}
8: 4770 bx lr
a: bf00 nop发布于 2013-11-30 21:27:05
错误消息的原因是ldr接受寄存器和内存引用,您提供了两次相同的寄存器。然后汇编程序将寄存器名解释为内存位置,因此抱怨没有在同一个文件中定义它。
由于寄存器已经用完,所以只能通过使用全局变量来避免堆栈使用。
https://stackoverflow.com/questions/20237493
复制相似问题