【发布时间】:2015-07-01 19:32:40
【问题描述】:
在 A64 汇编器中,有不同的方式来指定地址。
/*
[base{,#0}] Simple register (exclusive) - Immediate Offset
[base{,#imm}] Offset - Immediate Offset
[base,Xm{,LSL #imm}] Offset - Register Offset
[base,Wm,(S|U)XTW {#imm}] Offset - Extended Register Offset
[base,#imm]! Pre-indexed - Immediate Offset
[base],#imm Post-indexed - Immediate Offset
label PC-relative (literal) load - Immediate Offset
*/
我想在内联汇编器中使用“Offset - Immediate Offset”。
__asm__("ldp x8, x9, %0, 16 \n\t"
:
: "m" (*somePointer)
: "x8", "x9");
这被翻译成
ldp x8, x9, [x0], 16
我的目标是达到
ldp x8, x9, [x0, 16]
如何使用内联汇编编写这样的指令?
【问题讨论】:
-
我不知道你怎么能用只有 1 个参数的 %1 ?使用寄存器约束怎么样?警告:我还没有尝试过,但是
asm("ldp x8, x9, [%0, %1]" : : "r" (somePointer), "i"(16) : "x8", "x9");之类的呢? -
修复了这个问题 - 它显然应该是 %0。从具有更多输入/输出的较长语句中提取,并忘记更新参数:-) 这些提示对编译器来说不是很重要,以便它知道我的代码访问了哪些内存区域吗?例如如果我在写上下文中使用它,编译器可能需要知道我破坏了哪些内存区域 - 在这种情况下,寄存器约束将不起作用?
-
确实如此。所以由于编译器实际上并没有解析 asm,你可以这样做:
asm("ldp x8, x9, [%0, %1]" : : "r" (somePointer), "i"(16), "m" (*somePointer) : "x8", "x9");(即有约束,但不要引用它)。或添加“记忆”破坏者。请注意,正如所写,您只是告诉编译器 asm 读取内存,而不是更改它。
标签: c memory assembly inline-assembly arm64