Chinaunix首页 | 论坛 | 博客
  • 博客访问: 11338
  • 博文数量: 4
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 60
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-04 17:04
文章分类
文章存档

2010年(4)

我的朋友

分类: LINUX

2010-03-24 22:16:05

在内核中,常看到这样的代码:

int locked;

locked = xchg(&kexec_lock, 1);

在 include/asm-i386/cmpxchg.h 中,有如下定义:

#define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))

75 static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
76 {
77 switch (size) {
78 case 1:
79 __asm__ __volatile__("xchgb %b0,%1"
80 :"=q" (x)
81 :"m" (*__xg(ptr)), "" (x)
82 :"memory");
83 break;
84 case 2:
85 __asm__ __volatile__("xchgw %w0,%1"
86 :"=r" (x)
87 :"m" (*__xg(ptr)), "" (x)
88 :"memory");
89 break;
90 case 4:
91 __asm__ __volatile__("xchgl %0,%1"
92 :"=r" (x)
93 :"m" (*__xg(ptr)), "" (x)
94 :"memory");
95 break;
96 }
97 return x;
98 }

先看看什么是__typeof__。__typeof__(x)返回x的类型,并在编译时用返回的类 型进行替换。看一个例子:

 
int a;
__typeof__(a) b;

相当于int b;

由于具有这样的硬类型替换,因此被大量用到宏中。

接下来再看看xchg,xchg在i386中是被用来交换两个数据。来看以下下面的内联 汇编:

__asm__ __volatile__("xchgl %0,%1"
:"=r" (x)
:"m" (*__xg(ptr)), "" (x)
:"memory");

想要看懂这样的汇编语句,需要知道一点AT&T的汇编语法和GCC的内联汇编语法。 "=r" (x)表明X将作为结果的输出。r和=都是操作限定符号。r表示可以使用任何 寄存器,而=表示这是一个输出操作,并且是只写的。

而这里的输入则是ptr和x,其中,%0指向x,而%1指向ptr. m是内存操作限定符 号,它表示跳过寄存器直接对内存操作。

最后一行的memory表示我们的操作是在一个不可预知的内存区域上进行的。

因此,上面的汇编语句就是输入两个数,然后交换这两个数,并把交换后的一个 写回变量中。

但是,仅仅交换两个数,就用汇编来实现,难道只是为了效率?

阅读(2397) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~