linux – ARM inline asm:退出系统调用,从内存中读取值
作者:互联网
问题
我想在Linux Android设备上使用内联汇编在ARM中执行退出系统调用,我希望从内存中的某个位置读取退出值.
例
如果不给出这个额外的参数,调用的宏看起来像:
#define ASM_EXIT() __asm__("mov %r0, #1\n\t" \
"mov %r7, #1\n\t" \
"swi #0")
这很好用.
要接受一个参数,我将其调整为:
#define ASM_EXIT(var) __asm__("mov %r0, %0\n\t" \
"mov %r7, #1\n\t" \
"swi #0" \
: \
: "r"(var))
我用它来称呼它:
#define GET_STATUS() (*(int*)(some_address)) //gets an integer from an address
ASM_EXIT(GET_STATUS());
错误
invalid ‘asm’: operand number out of range
我无法解释为什么我会收到此错误,因为我在上面的代码段(%0 / var)中使用了一个输入变量.此外,我尝试了一个常规变量,仍然有同样的错误.
解决方法:
Extended-asm syntax需要编写%%以获得asm输出中的单个%.例如对于x86:
asm("inc %eax") // bad: undeclared clobber
asm("inc %%eax" ::: "eax"); // safe but still useless :P
%r7将r7视为操作数.正如评论者指出的那样,只要省略%s,因为即使使用GNU,你也不需要它们用于ARM.
不幸的是,有doesn’t seem to be a way to request input operands in specific registers on ARM,你可以为x86的方式. (例如,“a”约束特别指eax).
您可以使用register int var asm(“r7”)强制var使用特定寄存器,然后使用“r”约束并假设它将在该寄存器中.我不确定这总是安全的,或者是一个好主意,但它似乎在内联之后仍然有效. @Jeremy评论说这项技术是GCC团队推荐的.
我确实得到了一些有效的代码,这避免了在reg-reg移动上浪费指令:
See it on the Godbolt Compiler Explorer:
__attribute__((noreturn)) static inline void ASM_EXIT(int status)
{
register int status_r0 asm ("r0") = status;
register int callno_r7 asm ("r7") = 1;
asm volatile("swi #0\n"
:
: "r" (status_r0), "r" (callno_r7)
);
}
#define GET_STATUS() (*(int*)(some_address)) //gets an integer from an address
void foo(void) { ASM_EXIT(12); }
push {r7} @ # gcc is still saving r7 before use, even though it sees the "noreturn" and doesn't generate a return
movs r0, #12 @ stat_r0,
movs r7, #1 @ callno,
swi #0
# yes, it literally ends here, after the inlined noreturn
void bar(int status) { ASM_EXIT(status); }
push {r7} @
movs r7, #1 @ callno,
swi #0 # doesn't touch r0: already there as bar()'s first arg.
由于您总是希望从内存中读取值,因此可以使用“m”约束并在内联asm中包含ldr.然后你不需要寄存器int var asm(“r0”)技巧来避免该操作数浪费的mov.
可能并不总是需要mov r7,#1,这也是我使用寄存器asm()语法的原因.如果gcc在函数中的某个其他位置的寄存器中想要1个常量,那么它可以在r7中执行它,因此它已经存在于ASM_EXIT中.
每当GNU C内联asm语句的第一个或最后一个指令都是mov指令时,可能有一种方法可以用更好的约束来删除它们.
标签:linux,assembly,arm,system-calls,inline-assembly 来源: https://codeday.me/bug/20190829/1758244.html