标签:
static inline void arch_spin_lock(arch_spinlock_t *lock)
{
unsigned long tmp;
__asm__ __volatile__(
"1: ldrex %0, [%1]\n"
" teq %0, #0\n"
WFE("ne")
" strexeq %0, %2, [%1]\n"
" teqeq %0, #0\n"
" bne 1b"
: "=&r" (tmp)
: "r" (&lock->lock), "r" (1)
: "cc");
smp_mb();
}
内嵌汇编的通用形式:
__asm__ __volatile__ (
代码
: 输出操作数列表
: 输入操作数列表
: registers-modified
);
在一个asm语句中可以写一条或者多条汇编代码,一条汇编代码结束采用\n进行换行,有时候,也采用\n\t进行换行。
C语言通过变量的形式访问数据,而汇编语言是通过内存地址或者直接访问寄存器的方式访问数据,如果要在内嵌汇编中访问C语言中的变量,并且修改它的值的话,那么就需要用一种方式用于相互转换C语言的变量与内嵌汇编能访问的寄存器或内存地址形式。这种方式就是通过输入操作数列表和输出操作数列表实现的。
输入和输出操作数列表的格式是一样的,都是由一个或者多个操作数组成,中间采用逗号进行分开,单个操作的格式如下:
[C变量在汇编中的访问名称] "限制性字符“ (C传递进来的变量名称)
常用限制符:
m Any valid memory address,有效内存地址
r General register r0 .. r15,通用寄存器r0~r15
I Immediate value in data processing instructions
上面这些限制性字符如果不带修饰符的话,表示是只读操作数,只能用于输入操作数列表中。对于输出操作数列表中的操作数我们需要加上相应的写权限。常用修饰符包括如下:
= Write-only operand, usually used for all output operands 只写操作数,通常用于所有的输出操作数。
+ Read-write operand, must be listed as an output operand 读写操作。
& A register that should be used for output only 只用作输出的寄存器。(表示不能与输入寄存器用同样一个寄存器)
asm __volatile__(
"mcr p15, 0, %[domain], c3, c0, 0\n\t" //domain
"mcr p15, 0, %[ttb], c2, c0, 0\n\t" //ttb_base
"mrc p15, 0, r0, c1, c0, 0\n\t" //mmu enable
"orr r0, r0, #1\n\t"
"orr r0, r0, #(1<<13)\n\t"
"mcr p15, 0, r0, c1, c0, 0\n\t"
:
: [ttb] "r" (ttb), [domain] "r" (0xffffffff) //%0--->ttb, %1--->domain
: "memory", "r0"
);
通常在内嵌汇编中我们使用%0,%1之类的访问输入或输出操作数,但我们也可以自定义变量来访问,且内嵌汇编中的变量名与C中的变量名相同也不会有问题。
“cc”:你使用的指令会改变CPU的条件寄存器cc;
“memory”:你使用的指令会修改内存;
内嵌汇编
标签:
原文地址:http://www.cnblogs.com/black-mamba/p/5027685.html