【问题标题】:inline assembly error: can't find a register in class 'GENERAL_REGS' while reloading 'asm'内联汇编错误:重新加载“asm”时在“GENERAL_REGS”类中找不到寄存器
【发布时间】:2011-05-31 07:56:08
【问题描述】:

我有一个内联 AT&T 样式的汇编块,它适用于 XMM 寄存器,并且在我的 Release 配置中没有问题>XCode 项目,但是我在 Debug 配置中偶然发现了这个奇怪的错误(这应该是 GCC 错误)...我能以某种方式修复它吗?汇编代码没有什么特别的,但是我使用了很多内存约束(12个约束),这会导致这个问题吗?

【问题讨论】:

    标签: xcode gcc assembly constraints inline-assembly


    【解决方案1】:

    不是一个完整的答案,抱歉,但是 cmets 部分太短了...

    您能否发布一个示例 asm("..." :::) 行来演示该问题?

    XMM 寄存器的使用不是问题,错误信息表明 GCC 想要创建代码,比如:

    movdqa (%rax),%xmm0
    

    即内存通过保存在通用寄存器中的指针加载/存储,并且您指定的内存位置比可用的通用 regs 多(在调试模式下可能是 12,因为RBPRSP 用于帧/堆栈指针,并且可能RBX用于全局偏移表,RAX 保留用于返回)而没有实现寄存器重用的潜力。

    您可以通过以下方式解决问题:

    void *all_mem_args_tbl[16] = { memarg1, memarg2, ... };
    void *trashme;
    
    asm ("movq (%0), %1\n\t"
         "movdqa (%1), %xmm0\n\t"
         "movq 8(%0), %1\n\t"
         "movdqa (%1), %xmm1\n\t"
         ...
         : "r"all_mem_args_tbl : "r"(trashme) : ...);
    

    即将所有内存位置放入您作为操作数传递的表中,然后自行管理实际的通用寄存器使用。可能是通过间接表访问两个指针,但如果不知道完整的汇编代码段,很难说这是否会有所不同。

    【讨论】:

      【解决方案2】:

      Debug 配置默认使用-O0。由于此标志禁用优化,编译器可能无法根据您的内联汇编代码指定的约束分配寄存器,从而导致寄存器不足。

      一种解决方案是指定不同的优化级别,例如-Os,Release 配置中默认使用的那个。

      【讨论】:

      • @Ryan 这很奇怪。检查编译 Release 构建时发出的命令行调用,并将其与相应的 Debug 构建调用进行比较。
      • 嗯,Debug 和 Release 配置之间的唯一区别是 SSE3 / 补充 SSE3 指令的使用...
      • @Ryan 如果在 Debug 配置中启用 SSE3 是否有效?
      • @Ryan 如果您编辑了您的问题并发布了两种配置的实际命令行调用,将会有所帮助。
      • 我无法编辑我的问题,因为我是未注册用户...如果是发布版本,调用是 /Developer/usr/bin/gcc-4.2 -x c++ -arch i386 - fmessage-length=0 -pipe -Wno-trigraphs -fpascal-strings -fasm-blocks -Os -isysroot /Developer/SDKs/MacOSX10.6.sdk -msse3 -mssse3 -fvisibility-inlines-hidden -mmacosx-version-min= 10.6 -gdwarf-2 -iquote...
      猜你喜欢
      • 1970-01-01
      • 2016-03-19
      • 1970-01-01
      • 2012-05-13
      • 1970-01-01
      • 2015-09-25
      • 2011-04-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多