免费注册 查看新帖 |

Chinaunix

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

gcc inline asm的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-01-18 23:53 |只看该作者 |倒序浏览
本帖最后由 baozhao 于 2011-01-18 23:59 编辑

代码如下,请问 %P2 是何意义?THREAD_GETMEM_NC中%P为何又不见了呢?
/* Read member of the thread descriptor directly.  */
#define THREAD_GETMEM(descr, member) \
({                                                                              \
  __typeof__ (descr->member) __value;                                              \
  if (sizeof (__value) == 1)                                                      \
    __asm__ __volatile__ ("movb %%gs:%P2,%b0"                                      \
                          : "=q" (__value)                                      \
                          : "0" (0),                                              \
                            "i" (offsetof (struct _pthread_descr_struct,      \
                                           member)));                              \
  else if (sizeof (__value) == 4)                                              \
    __asm__ __volatile__ ("movl %%gs:%P1,%0"                                      \
                          : "=r" (__value)                                      \
                          : "i" (offsetof (struct _pthread_descr_struct,      \
                                           member)));                              \
  else                                                                              \
    {                                                                              \
      if (sizeof (__value) !=  8                                              \
        /* There should not be any value with a size other than 1, 4 or 8.  */\
        abort ();                                                              \
                                                                              \
      __asm__ __volatile__ ("movl %%gs:%P1,%%eax\n\t"                              \
                            "movl %%gs:%P2,%%edx"                              \
                            : "=A" (__value)                                      \
                            : "i" (offsetof (struct _pthread_descr_struct,    \
                                             member)),                              \
                              "i" (offsetof (struct _pthread_descr_struct,    \
                                             member) + 4));                      \
    }                                                                              \
  __value;                                                                      \
})

/* Same as THREAD_GETMEM, but the member offset can be non-constant.  */
#define THREAD_GETMEM_NC(descr, member) \
({                                                                              \
  __typeof__ (descr->member) __value;                                              \
  if (sizeof (__value) == 1)                                                      \
    __asm__ __volatile__ ("movb %%gs:%2),%b0"                                      \
                          : "=q" (__value)                                      \
                          : "0" (0),                                              \
                            "r" (offsetof (struct _pthread_descr_struct,      \
                                           member)));                              \
  else if (sizeof (__value) == 4)                                              \
    __asm__ __volatile__ ("movl %%gs:%1),%0"                                      \
                          : "=r" (__value)                                      \
                          : "r" (offsetof (struct _pthread_descr_struct,      \
                                           member)));                              \
  else                                                                              \
    {                                                                              \
      if (sizeof (__value) != 8                                             \
        /* There should not be any value with a size other than 1, 4 or 8.  */\
        abort ();                                                              \
                                                                              \
      __asm__ __volatile__ ("movl %%gs:%1),%%eax\n\t"                              \
                            "movl %%gs:4(%1),%%edx"                              \
                            : "=&A" (__value)                                      \
                            : "r" (offsetof (struct _pthread_descr_struct,    \
                                             member)));                              \
    }                                                                              \
  __value;                                                                      \
})

论坛徽章:
2
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:53:17
2 [报告]
发表于 2011-01-19 11:20 |只看该作者
笔记,凑合着看吧:

        5, UNDOCUMENTED: %c0, %n0, %l0, %P0 ....

           有时侯我们会想这么写一条汇编语句:

                /* 错误写法 */
                asm volatile ("movl %0(%%esp), %%eax" : /* no outputs */ : "i" (-1) );

           但这样子gcc会报错:

                Error: junk `(%esp)' after expression

           猜测原因是,%0是立即数(用"i"指定了的),于是gcc会把这条汇编指令变成:

                movl $-1(%esp), %eax

           于是它就会报错,因为多了一个无用的$符号。

           需要改成:

                asm volatile ("movl %P0(%%esp), %%eax" : /* no outputs */ : "i" (-1) );

例子:/*{{{*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>


int main(void)
{
        unsigned long p1, p2, p3, p4;
        p1 = p2 = p3 = p4 = 0;

        asm volatile ("leal %P4(%%esp), %0\n\t"
                      "leal %P5(%%esp), %1\n\t"
                      "leal %P6(%%esp), %2\n\t"
                      "leal %P7(%%esp), %3\n\t"
                      : "=r" (p1) , "=r" (p2), "=r" (p3), "=r" (p4)
                      : "i" (-1), "i" (-2), "i" (-3), "i" (-4)
                     );

        /* core2上的输出:
         * p1 is bfde32af, p2 is bfde32ae, p3 is bfde32ad, p4 is bfde32ac
         */
        printf("p1 is %x, p2 is %x, p3 is %x, p4 is %x\n", p1, p2, p3, p4);


        return 0;
}
/*}}}*/

                %c0
                %n0
                %l0
                %P0

评分

参与人数 1可用积分 +30 收起 理由
Godbach + 30 感谢分享

查看全部评分

论坛徽章:
0
3 [报告]
发表于 2011-01-19 19:52 |只看该作者
回复 2# 帅绝人寰


找到一个类似的    http://linux.chinaunix.net/bbs/viewthread.php?tid=901519
里面说 P -- if PIC, print an @PLT suffix.  如何理解? %c0的用法似乎明白了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP