简体   繁体   English

内联汇编错误:在重新加载“asm”时在 class 'GENERAL_REGS' 中找不到寄存器

[英]inline assembly error: can't find a register in class 'GENERAL_REGS' while reloading 'asm'

I have an inline AT&T style assembly block, which works with XMM registers and there are no problems in Release configuration of my XCode project, however I've stumbled upon this strange error (which is supposedly a GCC bug) in Debug configuration... Can I fix it somehow?我有一个内联AT&T样式的汇编块,它适用于XMM寄存器,并且在我的XCode项目的发布配置中没有问题,但是我在调试配置中偶然发现了这个奇怪的错误(据说是GCC错误)...我可以以某种方式修复它吗? There is nothing special in assembly code, but I am using a lot of memory constraints ( 12 constraints ), can this cause this problem?汇编代码没什么特别的,但是我用了很多memory约束( 12个约束),会不会导致这个问题?

The Debug configuration uses -O0 by default. Debug 配置默认使用-O0 Since this flag disables optimisations, the compiler is probably not being able to allocate registers given the constraints specified by your inline assembly code, resulting in register starvation.由于此标志禁用优化,编译器可能无法根据您的内联汇编代码指定的约束分配寄存器,从而导致寄存器不足。

One solution is to specify a different optimisation level, eg -Os , which is the one used by default in the Release configuration.一种解决方案是指定不同的优化级别,例如-Os ,这是发布配置中默认使用的优化级别。

Not a complete answer, sorry, but the comments section is too short for this...不是一个完整的答案,对不起,但评论部分太短了......

Can you post a sample asm("...":::) line that demonstrates the problem?您可以发布一个示例asm("...":::)行来演示该问题吗?

The use of XMM registers is not the issue, the error message indicates that GCC wanted to create code like, say:使用 XMM 寄存器不是问题,错误消息表明 GCC 想要创建代码,例如:

movdqa (%rax),%xmm0

ie memory loads/stores through pointers held in general registers, and you specified more memory locations than available general-purpose regs (it's probably 12 in debug mode because because RBP , RSP are used for frame/stackpointer and likely RBX for the global offset table and RAX reserved for returns) without realizing register re-use potential.即 memory 通过保存在通用寄存器中的指针加载/存储,并且您指定的 memory 位置比可用的通用 regs 更多(在调试模式下可能为 12,因为因为RBPRSP用于帧/堆栈指针,并且可能用于全局偏移量的表RBXRAX保留用于返回)而没有意识到寄存器重用的潜力。

You might be able to eek things out by doing something like:您可以通过执行以下操作来解决问题:

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) : ...);

ie put all the mem locations into a table that you pass as operand, and then manage the actual general-purpose register use on your own.即把所有的内存位置放到一个你作为操作数传递的表中,然后你自己管理实际的通用寄存器使用。 It might be two pointer accesses through the indirection table, but whether that makes a difference is hard to say without knowing your complete assembler code piece.它可能是通过间接表访问两个指针,但是如果不知道完整的汇编代码段,很难说这是否会有所不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM