免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4580 | 回复: 1
打印 上一主题 下一主题

xchg作用 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-03-20 16:54 |只看该作者 |倒序浏览
xchg并不是交换两值,看一部分:
#define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long) \
                                         (v),(ptr),sizeof(*(ptr))))
static inline unsigned long __xchg(unsigned long x,
                                  volatile void * ptr, int size)
{
    switch (size) {
        case 1:
            __asm__ __volatile__("xchgb %b0,%1"
                :"=q" (x)
                :"m" (*__xg(ptr)), "0" (x)
                :"memory");
            break;
        case 2:
            __asm__ __volatile__("xchgw %w0,%1"
                :"=r" (x)
                :"m" (*__xg(ptr)), "0" (x)
                :"memory");
            break;
        case 4:
            __asm__ __volatile__("xchgl %0,%1"
                :"=r" (x)
                :"m" (*__xg(ptr)), "0" (x)
                :"memory");
            break;
    }
    return x;
}
它只是将第二个参数x放入寄存器中与第一个指针参数所指的内容交换,返回所指内容原先的值。谈不上两数交换值。但是它可以“原子”的设置ptr所指内容并取出原值,这正是我们想要的。
可以参考一下下面小程序的结果:
#include
int main()
{
    int i = 1,j = 2;
    printf("i=%d, j=%d\n", i, j);
    printf("xchg:%d\n", xchg(&i, j));
    printf("i=%d, j=%d\n", i, j);
    return 0;
}
结果为:
i=1, j=2
xchg:1
i=2, j=2


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/93336/showart_1870112.html

论坛徽章:
0
2 [报告]
发表于 2013-09-23 23:23 |只看该作者
纠正一下楼主,确实是交换了,你的测试程序里最后j还是等于2,是因为xchg()函数调用传递的是j的副本(值传递)。在xchg()函数返回之前,其2个形参确有交换。
参考代码:------------------------------------------------------------------------
#include <stdio.h>

struct __xchg_dummy { unsigned long a[100]; };
#define __xg(x) ((struct __xchg_dummy *)(x))

static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
{
        printf("j=%d, *ptr=%d\n", (int)x, *(int *)ptr);        // add
        switch (size) {
                case 1:
                        __asm__ __volatile__("xchgb %b0,%1"
                                :"=q" (x)
                                :"m" (*__xg(ptr)), "0" (x)
                                :"memory");
                        break;
                case 2:
                        __asm__ __volatile__("xchgw %w0,%1"
                                :"=r" (x)
                                :"m" (*__xg(ptr)), "0" (x)
                                :"memory");
                        break;
                case 4:
                        __asm__ __volatile__("xchgl %0,%1"
                                :"=r" (x)
                                :"m" (*__xg(ptr)), "0" (x)
                                :"memory");
                        break;
        }
        printf("j=%d, *ptr=%d\n", (int)x, *(int *)ptr);        // add
        return x;
}

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

int main(int argc, char** argv)

{
     int i = 1,j = 2;
     printf("i=%d, j=%d\n", i, j);
     printf("xchg:%d\n", xchg(&i, j));
     printf("i=%d, j=%d\n", i, j);
     return 0;
}
运行结果:
i=1, j=2
j=2, *ptr=1
j=1, *ptr=2
xchg:1
i=2, j=2
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP