嵌入式Linux中ARM gcc嵌套汇编学习-ARM GCC Inside Assembler

在使用gcc编译的时候,可以在C语言程序中嵌套汇编指令,这样极大的方便在高级语言中使用跟配件相关的指令。

在gcc中嵌套的汇编指令跟纯汇编文件的语法有一点不一样,在gcc中嵌套指令的格式是固定的:

__asm__(code : output operand list : input operand list : clobber list);
__asm__(汇编语句模板 : 输出部分 :输入部分 :破坏描述部分);
其中包括四个部分,每个部分之间使用":"分开
汇编语句模板是汇编命令的字符串,输出部分是需要输出到C变量参数列表,
输入部分是需要从C变量输入到ASM汇编的参数列表,破坏描述部分是指执行汇编指令会破坏的寄存器描述。
第一部分是必须写的,后面三部分是可以省略,但是分号":"不能省略!
例如
__asm__("cli":::)
 
一个嵌套汇编块里面可以写多条汇编指令,指令之间需要换行符隔开“\n"或分号";"隔开
__asm__("mrs	r0, cpsr \n"			 \
               "orr	r0,  r0, #128\n"	\
		"msr	cpsr_c, r0" :
		:
		:)

嵌套汇编里面可以访问C语言所定义的变量,
可以在输入部分,给汇编指令传递C语言定义的参数,也可以把汇编指令中得到的值传递到C语言所定义的变量中。
例如:
	unsigned long x;					
	unsigned long temp;	
	(void) (&temp == &x);
	__asm__ __volatile__(
	"mrs	%0, cpsr	\n"			\
	"orr	%1, %0, #128   \n"		\
	"msr	cpsr_c, %1"			\
	: "=r" (x), "=r" (temp)		\
	:
	: "memory", "cc");
	})
上面代码中,%0表示第一个参数,%1表示第二个参数,依此类推,可以得到其它的参数,
这是老版本的gcc的方法了,好像只可以支持到10个参数吧?
新版本的是可以直接在汇编中使用参数名的访问的,呵呵,不过大部分源码还是使用%0的方法,所以在这也只看这个方法吧,,,
 "=r" (x), "=r" (temp)
这里是输出的列表,每个参数是以逗号","隔开的,
"=r"(x)表示asm中第一个参数的值保存到变量x中. 
"=r"(temp)表示asm中第二个参数的值保存到变量temp中. 


如果是需要输入参数的话,则把"="号去除,
	unsigned long x;
	__asm__ __volatile__(
	"msr	cpsr_c, %0 \n"	\
	:
	: "r" (x)
	: "memory", "cc")
上面代码就是把变量x传入到汇编指令当中去,后面的破坏描述符会告诉编译器哪个寄存器被使用了,避免寄存器使用冲突。
"memory"描述符表示
1.将不重新排序该段内嵌汇编指令与前面的指令。
2.不使用寄存器作为缓存。
呵呵,这个只是简单参考网上文章得到的,如果需要进一步了解可以去读一下

ARM GCC Inline Assembler Cookbook

你可能感兴趣的:(C++,c,linux,gcc,嵌入式)