在内联汇编宏中作为值的标签
Labels as Values in Inline Assembly Macros
我想知道如何在内联汇编中加载具有标签值的寄存器。
我天真地尝试过以这种方式进行操作:
#define inline_macro(a) \
asm volatile("1: movw %[rega], #:lower16:1b\n" \
" movt %[rega], #:upper16:1b\n" \
: [rega] "+r" (a) \
: \
: \
);
int main(void){
register int i asm("r2");
register void* value asm("r1");
i++;
i += 2;
inline_macro(value);
return i;
}
但是,对象转储显示正在生成此汇编代码:
00000000 <main>:
0: e52db004 push {fp} ; (str fp, [sp, #-4]!)
4: e28db000 add fp, sp, #0
8: e1a03002 mov r3, r2
c: e2833001 add r3, r3, #1
10: e1a02003 mov r2, r3
14: e1a03002 mov r3, r2
18: e2833002 add r3, r3, #2
1c: e1a02003 mov r2, r3
00000020 <.L11>:
20: e3001000 movw r1, #0
24: e3401000 movt r1, #0
28: e1a03002 mov r3, r2
2c: e1a00003 mov r0, r3
30: e24bd000 sub sp, fp, #0
34: e49db004 pop {fp} ; (ldr fp, [sp], #4)
38: e12fff1e bx lr
我想要的是将值 0x20 加载到寄存器 r1。
我不知道 arm asm,但你正在尝试获取 movw
指令的地址? ARM 真的需要两个单独的 16 位 mov
指令吗?
看起来您正在反汇编 .o
,其中链接器没有用它们的实际值替换符号引用,并且您看到 0
作为占位符。
因为我认为你的代码不依赖于寄存器的旧值,你应该将它用作只写输出操作数(=r
),而不是读写操作数(+r
).
实际上有一整条指令可以将标签的地址存入寄存器:ADR
。
由于它在 PC 上通过算术工作,因此它完全与位置无关并且没有无限范围,但这似乎都不是问题 - 利用汇编程序的 "current instruction" 伪标签 .
,问题中的例子变成:
#define inline_macro(a) \
asm volatile("adr %[rega], . \n" \
: [rega] "=r" (a) \
: \
: \
);
我想知道如何在内联汇编中加载具有标签值的寄存器。
我天真地尝试过以这种方式进行操作:
#define inline_macro(a) \
asm volatile("1: movw %[rega], #:lower16:1b\n" \
" movt %[rega], #:upper16:1b\n" \
: [rega] "+r" (a) \
: \
: \
);
int main(void){
register int i asm("r2");
register void* value asm("r1");
i++;
i += 2;
inline_macro(value);
return i;
}
但是,对象转储显示正在生成此汇编代码:
00000000 <main>:
0: e52db004 push {fp} ; (str fp, [sp, #-4]!)
4: e28db000 add fp, sp, #0
8: e1a03002 mov r3, r2
c: e2833001 add r3, r3, #1
10: e1a02003 mov r2, r3
14: e1a03002 mov r3, r2
18: e2833002 add r3, r3, #2
1c: e1a02003 mov r2, r3
00000020 <.L11>:
20: e3001000 movw r1, #0
24: e3401000 movt r1, #0
28: e1a03002 mov r3, r2
2c: e1a00003 mov r0, r3
30: e24bd000 sub sp, fp, #0
34: e49db004 pop {fp} ; (ldr fp, [sp], #4)
38: e12fff1e bx lr
我想要的是将值 0x20 加载到寄存器 r1。
我不知道 arm asm,但你正在尝试获取 movw
指令的地址? ARM 真的需要两个单独的 16 位 mov
指令吗?
看起来您正在反汇编 .o
,其中链接器没有用它们的实际值替换符号引用,并且您看到 0
作为占位符。
因为我认为你的代码不依赖于寄存器的旧值,你应该将它用作只写输出操作数(=r
),而不是读写操作数(+r
).
实际上有一整条指令可以将标签的地址存入寄存器:ADR
。
由于它在 PC 上通过算术工作,因此它完全与位置无关并且没有无限范围,但这似乎都不是问题 - 利用汇编程序的 "current instruction" 伪标签 .
,问题中的例子变成:
#define inline_macro(a) \
asm volatile("adr %[rega], . \n" \
: [rega] "=r" (a) \
: \
: \
);