Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 如何理解这种嵌入式汇编代码?_Assembly_Arm_Cortex M3 - Fatal编程技术网

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

Assembly 如何理解这种嵌入式汇编代码?,assembly,arm,cortex-m3,Assembly,Arm,Cortex M3,我不明白 #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" (r

我不明白

#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;    \
})
这部分代码。特别是:
[ret]“+r”(ret)\

代码将arg1加载到r0,将arg2加载到r1,然后调用“svc call”,其中call是svc号码。然后,它将寄存器r0的值(由于svc指令而设置)移动到C变量ret中。


代码将arg1加载到r0,将arg2加载到r1,然后调用“svc call”,其中call是svc号码。然后,它将寄存器r0的值(由于svc指令而设置)移动到C变量ret中。

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

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

              "mov  %[ret], r0  \n" \
              :[ret] "+r" (ret)     \
              :[code] "I" (call), [ar1] "r" (arg1), [ar2] "r" (arg2)     \
              :"r0", "r1");         
定义此宏“函数”

设置ret=0,使其存在于堆栈外

uint32_t ret = 0;   \
将ar1移动到寄存器0中

asm volatile ("mov  r0, %[ar1]  \n"  \
将寄存器1移到

          "mov  r1, %[ar2]  \n"  \
主管呼叫已通过呼叫

          "svc  %[code]  \n"    \
将r0的内容移动到%[ret](后面我们看到的是在asm调用上方定义的ret int)

          "mov  %[ret], r0  \n" \
%[ret]是包含ret值的通用寄存器,ret作为输入/输出值传入

          :[ret] "+r" (ret)     \
[code]扩展为一段代码,作为调用传递到函数中,并将两个参数作为通用寄存器,我们在参数中传递ar1(保持arg1)和ar2(保持arg2)

          :[code] "I" (call), [ar1] "r" (arg1), [ar2] "r" (arg2)     \
和寄存器0和寄存器1

          :"r0", "r1");               \
“返回”ret

关闭“定义”对话框

“r”指通用寄存器 “+”表示输入/输出变量(类似于通过引用传递) “I”是特定于机器的,但给定上下文,它看起来是一段返回int的可调用代码

这些文件按以下格式排列在一起: :[thing_to_replace]“如何传递事物”(thing_to_pass)

有点像旧的printf替换,或sql准备语句中的替换

定义此宏“函数”

设置ret=0,使其存在于堆栈外

uint32_t ret = 0;   \
将ar1移动到寄存器0中

asm volatile ("mov  r0, %[ar1]  \n"  \
将寄存器1移到

          "mov  r1, %[ar2]  \n"  \
主管呼叫已通过呼叫

          "svc  %[code]  \n"    \
将r0的内容移动到%[ret](后面我们看到的是在asm调用上方定义的ret int)

          "mov  %[ret], r0  \n" \
%[ret]是包含ret值的通用寄存器,ret作为输入/输出值传入

          :[ret] "+r" (ret)     \
[code]扩展为一段代码,作为调用传递到函数中,并将两个参数作为通用寄存器,我们在参数中传递ar1(保持arg1)和ar2(保持arg2)

          :[code] "I" (call), [ar1] "r" (arg1), [ar2] "r" (arg2)     \
和寄存器0和寄存器1

          :"r0", "r1");               \
“返回”ret

关闭“定义”对话框

“r”指通用寄存器 “+”表示输入/输出变量(类似于通过引用传递) “I”是特定于机器的,但给定上下文,它看起来是一段返回int的可调用代码

这些文件按以下格式排列在一起: :[thing_to_replace]“如何传递事物”(thing_to_pass)


有点像旧的printf替换,或者sql准备语句中的替换。

mov和svc描述是错误的。I约束只是一个整数。为什么mov r0、%[ar1]意味着将r0移到ar1,而mov%[ret],r0表示将ret移动到r0?我认为mov方向是相同的。你是对的,我在第一个方向上犯了一个错误…匆忙造成浪费。编辑以修复。mov和svc描述是错误的。I约束只是一个整数。为什么mov r0,%[ar1]表示将r0移动到ar1,但mov%[ret],r0表示将ret移动到r0?我认为mov方向是相同的。你是对的,我在第一个方向上犯了一个错误…匆忙造成浪费。编辑以修复。