免费注册 查看新帖 |

Chinaunix

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

[实践] C中嵌入汇编代码,编译出错! [复制链接]

论坛徽章:
2
2015年迎新春徽章
日期:2015-03-04 09:57:09C
日期:2016-10-25 16:17:59
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-08-05 15:42 |只看该作者 |倒序浏览
本帖最后由 shaohui973 于 2013-08-05 15:43 编辑

代码如下:

void  strprintf(char *pcStr, int dwLen)
{
       __asm__("movl %1, %%edx\n\t"
                       "movl %0, %%ecx\n\t"
                       "movl $0, %%ebx\n\t"
                       "movl $4, %%eax\n\t"
                       "int $0x80\n\t"
                       :
                       :"0"(pcStr),"1"(dwLen)
                       :  );

       return;
}

编译错误为:
error:matching constraint references invalid operand number


我看不出变量和寄存机结合有什么错误。

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
2 [报告]
发表于 2013-08-05 18:28 |只看该作者
本帖最后由 瀚海书香 于 2013-08-05 18:28 编辑

回复 1# shaohui973

@smalloc 过来看看吧
   

论坛徽章:
7
丑牛
日期:2013-10-18 14:43:21技术图书徽章
日期:2013-11-03 09:58:03辰龙
日期:2014-01-15 22:57:50午马
日期:2014-09-15 07:04:39丑牛
日期:2014-10-16 14:25:222015年亚洲杯之伊朗
日期:2015-03-16 10:24:352015亚冠之城南
日期:2015-05-31 09:52:32
3 [报告]
发表于 2013-08-05 21:06 |只看该作者
本帖最后由 smalloc 于 2013-08-05 21:07 编辑

@瀚海书香 应该@老A
我只看出,给int80的参数传递是错的,
:"0"(pcStr),"1"(dwLen)
需要改为:
:dwLen,pcStr

论坛徽章:
3
双鱼座
日期:2013-09-04 19:47:39天蝎座
日期:2013-12-11 20:30:532015年亚洲杯之澳大利亚
日期:2015-04-20 00:28:02
4 [报告]
发表于 2013-08-05 23:32 |只看该作者
回复 1# shaohui973


     :"0"(pcStr),"1"(dwLen) -- 这里用法有问题.
我改成"m"(pcStr), "m"(dwLen)就可以编译通过了.

很明显你用错了数字约束。

"0”"1" 这种匹配约束(或者数字约束).常用于一种变量可能作为input,output操作数.
asm("incl %0" :"=a" (var) :"0"(var));   --- register %eax将作为输入和输出变量. var 将读%eax作为输入, 执行指令后将被更新的%eax再次保存在var中。 "0"将指定0th output variable 作为同一个约束.

论坛徽章:
7
丑牛
日期:2013-10-18 14:43:21技术图书徽章
日期:2013-11-03 09:58:03辰龙
日期:2014-01-15 22:57:50午马
日期:2014-09-15 07:04:39丑牛
日期:2014-10-16 14:25:222015年亚洲杯之伊朗
日期:2015-03-16 10:24:352015亚冠之城南
日期:2015-05-31 09:52:32
5 [报告]
发表于 2013-08-06 00:36 |只看该作者
回复 4# kiongf


    这位兄台,我觉得你找到的答案可能不完全,我猜想的是"0","1"约定本身和“寄存器模版”定义重合,即不定义"0""1",2个变量本身就被分配的是"0""1",而"0""1"这种约定是必须向前或向后重用的,结果是偏偏漏了自己,这个就报错了。

论坛徽章:
2
2015年迎新春徽章
日期:2015-03-04 09:57:09C
日期:2016-10-25 16:17:59
6 [报告]
发表于 2013-08-06 08:44 |只看该作者
回复 4# kiongf


    将输入约束中的样板寄存器"0"和"1"改成"m"确实可以编译通过。我想问下:
    "0"(pcStr)    不就是表示将变量pcStr和样板寄存器%0关联吗?

     能详细讲讲这个数据约束到底该怎么用?

论坛徽章:
2
2015年迎新春徽章
日期:2015-03-04 09:57:09C
日期:2016-10-25 16:17:59
7 [报告]
发表于 2013-08-06 08:45 |只看该作者
回复 5# smalloc


    这里不添加这个0和1样板寄存器约束时,他们本身是可以使用这些样板寄存器。

论坛徽章:
3
双鱼座
日期:2013-09-04 19:47:39天蝎座
日期:2013-12-11 20:30:532015年亚洲杯之澳大利亚
日期:2015-04-20 00:28:02
8 [报告]
发表于 2013-08-06 10:23 |只看该作者
回复 6# shaohui973


   
         "movl $4, %%eax\n\t"
                       "int $0x80\n\t"
                       :“=m” (whatever)
                       :"m"(pcStr),"m"(dwLen)
                       :  );

  有点类似于堆栈. whatever, pcStr,dwLen这些参数一起入栈,先入栈的第一个为%0,第二个%1这样依此类推。所以这里的%0是whatever, %1是pcStr, %2是dwLen.
当去掉whatever操作数时,
         "movl $4, %%eax\n\t"
                       "int $0x80\n\t"
                       :
                       :"m"(pcStr),"m"(dwLen)
                       :  );
%0则是pcStr, %1则是dwLen.
    当你使用“0”“1”这样的数字约束时, Gcc-inline-assembly中有提到, 该操作数是作为输入和输出使用.
        "movl $4, %%eax\n\t"
                       "int $0x80\n\t"
                       :“=m” (whatever) “=m” (whocare)
                       :"0"(whatever),"1"(whocare)
                       :  );
    典型的用法是这样子的.这样gcc就会把whatever从内存读入, 同时输出到内存中同一位置。whocare同理.

论坛徽章:
3
双鱼座
日期:2013-09-04 19:47:39天蝎座
日期:2013-12-11 20:30:532015年亚洲杯之澳大利亚
日期:2015-04-20 00:28:02
9 [报告]
发表于 2013-08-06 10:26 |只看该作者
回复 5# smalloc


    :wink:  我看的是比较老的gcc-inline-assembly手册, 可能改了.

论坛徽章:
7
丑牛
日期:2013-10-18 14:43:21技术图书徽章
日期:2013-11-03 09:58:03辰龙
日期:2014-01-15 22:57:50午马
日期:2014-09-15 07:04:39丑牛
日期:2014-10-16 14:25:222015年亚洲杯之伊朗
日期:2015-03-16 10:24:352015亚冠之城南
日期:2015-05-31 09:52:32
10 [报告]
发表于 2013-08-06 12:19 |只看该作者
回复 9# kiongf


    你是对的。gcc/stmt.c
          match = strtoul (constraint + j, &end, 10);
          if (match >= (unsigned long) noutputs)
            {
              error ("matching constraint references invalid operand number");
              return false;
            }
match是约定数字转换后的数,那么这个数必须在输出个数以内。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP