免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 6500 | 回复: 9

请教一个扩展汇编的问题 [复制链接]

论坛徽章:
0
发表于 2007-06-20 14:32 |显示全部楼层
我在内核代码看汇编的时候,不明白'=&r'和'=r'是什么区别,看了n多资料都一样的,就几句话,还是没看懂

论坛徽章:
2
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:53:17
发表于 2007-06-20 15:18 |显示全部楼层
Unless an output operand has the `&' constraint modifier, GCC may
allocate it in the same register as an unrelated input operand, on the
assumption the inputs are consumed before the outputs are produced.
This assumption may be false if the assembler code actually consists of
more than one instruction.  In such a case, use `&' for each output
operand that may not overlap an input.  *Note Modifiers::.


`&'
     Means (in a particular alternative) that this operand is an
     "earlyclobber" operand, which is modified before the instruction is
     finished using the input operands.  Therefore, this operand may
     not lie in a register that is used as an input operand or as part
     of any memory address.

     `&' applies only to the alternative in which it is written.  In
     constraints with multiple alternatives, sometimes one alternative
     requires `&' while others do not.  See, for example, the `movdf'
     insn of the 68000.

     An input operand can be tied to an earlyclobber operand if its only
     use as an input occurs before the early result is written.  Adding
     alternatives of this form often allows GCC to produce better code
     when only some of the inputs can be affected by the earlyclobber.
     See, for example, the `mulsi3' insn of the ARM.

     `&' does not obviate the need to write `='.

论坛徽章:
0
发表于 2007-06-20 15:52 |显示全部楼层
这个我看了,能解释一下吗?不明白用与不用的区别
我把一些代码翻译了一下,有没有&都是一样的,一个字的区别都没有

论坛徽章:
0
发表于 2007-06-20 16:03 |显示全部楼层
Unless an output operand has the `&' constraint modifier, GCC may
allocate it in the same register as an unrelated input operand, on the
assumption the inputs are consumed before the outputs are produced.
This assumption may be false if the assembler code actually consists of
more than one instruction.  In such a case, use `&' for each output
operand that may not overlap an input.
__________________

翻译一下:

&只是用来约束输出部的。  如果不指定&约束符, 则GCC有可能为一个输入操作数和该输出操作数使用同一个寄存器, 这是基于以下的假设: 在产生输出之前(把输出写入到寄存器), 作为输入的寄存器内容已经不再需要了。   有时侯嵌入汇编有很多条指令,这种假设可能是不对的, 有可能过早产生了输出, 从而覆盖了输入。  加上&约束,就会告诉gcc使用另一个寄存器, 不要和输入寄存器使用同一个。

论坛徽章:
0
发表于 2007-06-20 17:43 |显示全部楼层
有一丁点头绪,如果我理解对了,那么就是说'&'有时候是必须的,因为否则输入和输出的顺序在代码中要保持先后。
如果寄存器不够用,那么使用了'&'就表示在使用这个寄存器之前需要保存到某个内存中.

论坛徽章:
0
发表于 2007-06-20 18:01 |显示全部楼层
>> 如果寄存器不够用,那么使用了'&'就表示在使用这个寄存器之前需要保存到某个内存中.

(把原来的错误理解删除)

如果不加&符号, 举例来说, 如果寄存器不够用,GCC很可能为 输出操作数"=b"和输入操作数"a"使用同一个寄存器, 因为它假设: 在产生输出之前, 输入操作数就已经用完了,不需要了。

输出约束改成"=&b"能改变这一默认的优化。 "=&b"表示,这是一个"earlyclobber",可能会过早的损坏其他操作数,所以你为我单独分配个寄存器吧。    info手册说, 加上&只可能让gcc产生更优代码,没有副作用。



这个问题比较难在代码中试验,不过理论应该就是这样的。

[ 本帖最后由 albcamus 于 2007-6-21 09:38 编辑 ]

论坛徽章:
0
发表于 2007-06-22 11:05 |显示全部楼层
楼主弄明白这个问题没有?

论坛徽章:
0
发表于 2007-11-21 22:50 |显示全部楼层
今天翻精华,看见这个帖子,后来忘记这个帖子了
说实话,其实我还是没有完全理解,但是估计就是我现在理解的这个意思了

#include <stdio.h>
int main()
{
        unsigned short cs = 0;
        volatile unsigned short a,b,c,d,e,f;
        asm ("movw %%cs,%0\n\t"
                        :"=&r"(cs):"r"(a),"r"(b),"r"(c),"r"(d),"r"(e),"r"(f));
        printf("%x\n",cs);
}


这个代码编译出错,因为没有通用寄存器可用
但是如果没有&,则可以重用
        .file        "cs.c"
        .section        .rodata.str1.1,"aMS",@progbits,1
.LC0:
        .string        "%x\n"
        .text
        .p2align 4,,15
.globl main
        .type        main, @function
main:
        leal        4(%esp), %ecx
        andl        $-16, %esp
        pushl        -4(%ecx)
        pushl        %ebp
        movl        %esp, %ebp
        subl        $40, %esp
        movl        %ecx, -16(%ebp)
        movzwl        -18(%ebp), %edx/////
        movl        %ebx, -12(%ebp)
        movl        %esi, -8(%ebp)
        movl        %edi, -4(%ebp)
        movzwl        -20(%ebp), %edi
        movzwl        -22(%ebp), %esi
        movzwl        -24(%ebp), %ebx
        movzwl        -26(%ebp), %ecx
        movzwl        -28(%ebp), %eax
#APP
        movw %cs,%dx//dx是输入
      ####如果这个后面还有代码要使用a的值(dx),那么将不是a原始的值
       
#NO_APP
        movzwl        %dx, %edx
        movl        %edx, 4(%esp)
        movl        $.LC0, (%esp)
        call        printf
        movl        -16(%ebp), %ecx
        movl        -12(%ebp), %ebx
        movl        -8(%ebp), %esi
        movl        -4(%ebp), %edi
        movl        %ebp, %esp
        popl        %ebp
        leal        -4(%ecx), %esp
        ret
        .size        main, .-main
        .ident        "GCC: (GNU) 4.1.2 (Ubuntu 4.1.2-0ubuntu4)"
        .section        .note.GNU-stack,"",@progbits

论坛徽章:
0
发表于 2007-11-22 10:36 |显示全部楼层
我见过最好的两篇gcc inline asm文档
第一篇是很多人都看过的GCC inline Assembly HOWTO:
http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html

第二篇写的更好,是1998年LKML上的邮件:
http://groups.google.com/group/m ... ad/ca8860dd41ddd42b

论坛徽章:
0
发表于 2007-11-22 10:50 |显示全部楼层
第一篇看过,在你的博客中看到过,有时间看看
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP