assembly 如何理解这种嵌入式汇编代码?

pwuypxnk  于 2023-08-06  发布在  其他
关注(0)|答案(3)|浏览(94)
#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");


这部分代码。特别是:第一个月

sulc1iza

sulc1iza1#

这是gcc内联汇编语法。最后3行分别列出了输出、输入和clobbers。对于输出和输入,方括号中的部分是符号名称,可用于引用asm块中的特定参数。引号中的部分是告诉编译器它是哪种参数的约束:r表示寄存器,I表示立即数。+修饰符通常会告诉编译器参数是读写的,所以我不认为为返回值指定该修饰符有什么意义。最后圆括号中的部分是参数的值。因此,[ret] "+r" (ret)定义了一个名为[ret]的输出参数,该参数将位于寄存器中,并应分配给变量ret

pw9qyyiw

pw9qyyiw2#

#define SVC_ARG2(call, arg1, arg2)  ({ \

字符串
定义这个宏“函数”。

uint32_t ret = 0;   \


set ret = 0,所以它存在于out栈中。

asm volatile ("mov  r0, %[ar1]  \n"  \


将ar 1移动到寄存器0

"mov  r1, %[ar2]  \n"  \


将寄存器1移入

"svc  %[code]  \n"    \


主管呼叫已通过呼叫。

"mov  %[ret], r0  \n" \


将r 0的内容移动到%[ret]中(我们稍后会看到,它是在asm调用上方定义的ret int。

:[ret] "+r" (ret)     \


%[ret]是一个包含ret值的通用寄存器,ret作为输入/输出值传入。

:[code] "I" (call), [ar1] "r" (arg1), [ar2] "r" (arg2)     \


[code]扩展为一段代码,它作为调用传递到函数中,并接受两个参数,通用寄存器,我们将ar 1(持有arg 1)和ar 2(持有arg 2)作为参数传递。

:"r0", "r1");               \


和寄存器0和寄存器1

ret;    \


“返回”ret

})


关闭定义。
“r”表示通用寄存器“+”表示in/out变量(有点像通过引用传递)“I”是特定于机器的,但给定上下文看起来是一段返回int的可调用代码。
它们以如下格式排列在一起::[thing_to_replace]“如何传递事物”(thing_to_pass)
类似于旧的printf替换,或者sql准备语句中的替换。

cu6pst1q

cu6pst1q3#

http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
代码将arg1加载到r0,arg2加载到r1,然后调用“svc call”,其中call是SVC编号。然后,它将寄存器r0的值(由于svc指令而被设置)移动到C变量ret中。

相关问题