#define SVC_ARG2(call, arg1, arg2) ({ \
uint32_t ret = 0; \
asm volatile ("mov r0, %[ar1] \n" \
"mov r1, %[ar2] \n" \
"svc %[code] \n" \
"mov %[ret], r0 \n" \
:[ret] "+r" (ret) \
:[code] "I" (call), [ar1] "r" (arg1), [ar2] "r" (arg2) \
:"r0", "r1"); \
ret; \
})
字符串
我不明白
"mov %[ret], r0 \n" \
:[ret] "+r" (ret) \
:[code] "I" (call), [ar1] "r" (arg1), [ar2] "r" (arg2) \
:"r0", "r1");
型
这部分代码。特别是:第一个月
3条答案
按热度按时间sulc1iza1#
这是gcc内联汇编语法。最后3行分别列出了输出、输入和clobbers。对于输出和输入,方括号中的部分是符号名称,可用于引用asm块中的特定参数。引号中的部分是告诉编译器它是哪种参数的约束:
r
表示寄存器,I
表示立即数。+
修饰符通常会告诉编译器参数是读写的,所以我不认为为返回值指定该修饰符有什么意义。最后圆括号中的部分是参数的值。因此,[ret] "+r" (ret)
定义了一个名为[ret]
的输出参数,该参数将位于寄存器中,并应分配给变量ret
。pw9qyyiw2#
字符串
定义这个宏“函数”。
型
set ret = 0,所以它存在于out栈中。
型
将ar 1移动到寄存器0
型
将寄存器1移入
型
主管呼叫已通过呼叫。
型
将r 0的内容移动到%[ret]中(我们稍后会看到,它是在asm调用上方定义的ret int。
型
%[ret]是一个包含ret值的通用寄存器,ret作为输入/输出值传入。
型
[code]扩展为一段代码,它作为调用传递到函数中,并接受两个参数,通用寄存器,我们将ar 1(持有arg 1)和ar 2(持有arg 2)作为参数传递。
型
和寄存器0和寄存器1
型
“返回”ret
型
关闭定义。
“r”表示通用寄存器“+”表示in/out变量(有点像通过引用传递)“I”是特定于机器的,但给定上下文看起来是一段返回int的可调用代码。
它们以如下格式排列在一起::[thing_to_replace]“如何传递事物”(thing_to_pass)
类似于旧的printf替换,或者sql准备语句中的替换。
cu6pst1q3#
http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
代码将arg1加载到r0,arg2加载到r1,然后调用“svc call”,其中call是SVC编号。然后,它将寄存器r0的值(由于svc指令而被设置)移动到C变量ret中。