参考网址:https://www.cnblogs.com/lifexy/p/8075282.html
示例程序
#include <errno.h> #include <unistd.h> #define __NR_SYSCALL_BASE 0x900000 void hello(char *buf, int count) { /* swi */ asm ("mov r0, %0\n" /* save the argment in r0 */ //%0等于buf "mov r1, %1\n" /* save the argment in r0 */ //%1等于count "swi %2\n" /* do the system call */ //%2等于0x900352 : //输出部 : "r"(buf), "r"(count), "i" (__NR_SYSCALL_BASE + 352) //输入部 : "r0", "r1"); //损坏部,指原有的数据会被破坏 } int main(int argc, char **argv) { printf("in app, call hello\n"); hello("www.100ask.net", 15);//这个函数会调用内核的sys_hello() return 0; }
4.1 其中asm ()是一个内嵌汇编(参考linux内核源代码情景分析1.5.2节)
格式如下所示:
- asm( 指令部 : 输出部 : 输入部 : 损坏部 );
指令部
在指令部中,若出现%0、%1、%2等,则表示指令部后面的第几个变量.
比如上面代码的"mov r0, %0\n".
其中%0便会对应buf值,而"r"是一个约束条件字母,r表示任意一个寄存器,在预处理时,便会自动分配一个寄存器,将buf值放入该寄存器里,然后运行mov r0 (buf对应的寄存器)
输出部
每个输出部的约束条件字母都要加上"=",比如:
int num=5,val; asm("mov %0,%1\n" :"=r"(val) //指定val是一个输出部,执行mov后,val便等于5 :"i"(num) // "i"约束条件字母,表示num是一个立即数 : );
输入部
和输出部唯一不同的就是,在约束条件字母前不能加上"="
常用的约束条件字母,如下图所示:
损坏部
和输入输出类似,一般用来处理操作的中间过程,因为这些原有的内容都会被损坏,比如上面的hello()里的"r0", "r1",只是用来当做参数,传递给内核的sys_hello()