错误:"asm"中不可能的寄存器约束 [英] error: impossible register constraint in 'asm'

查看:458
本文介绍了错误:"asm"中不可能的寄存器约束的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在编译软件包时遇到问题,我不是 确实是一个很好的编码器,但是我尝试自己修复它,但仍然无法编译. 这是原始代码.

I've run into a problem while compiling a package around, I am not really a good coder, but I tried fixing it for my self, and it still won't compile. This is the original bit of code.:

#ifdef __GNUC__
asm("and $3, %%ecx;"
"shl $3 ,%%ecx;"
"ror %%cl, %0"
: "=r" (value)
: "r" (value), "c" (address));
#else

错误是.:

GBAinline.h:139:错误:"asm"中无法进行寄存器约束 (ifdef行是138)

GBAinline.h:139: error: impossible register constraint in 'asm' ( ifdef line is 138 )

这就是我试图使其外观的方式.

And this is how I tried to make it look.:

#ifdef __GNUC__
asm ("and $3 %%ecx,shl $3 %%ecx,ror %%cl, %0" : "=r" (value): "r" (value), "c" (address));

#else

仍然,它将无法正常工作.这是一个在任何人都问过之前的gba模拟器,VBA,这是 GBAinline.h的一部分.这个汇编器已经让我发疯了.

Still, it would not work. It's a gba emulator before anyone ask, VBA, and this is part of GBAinline.h . This assembler is making me crazy already.

编辑.:上面的问题已经很好地处理了,我只是不注意哪个 我正在使用的编译器. 但是现在我从头文件中的这段代码中得到了这个错误,我将其放在pastebin上, 为了使这里的内容更整洁...(对不起,如果这是错误的,我可以稍后再更改)

Edit.: The problem above was handled fine, I just was not paying attention to which compiler I was using. But now I get this error on this bit of code from a header file, I've put it on pastebin, to keep things here a bit more tidy... ( Sorry if this is wrong, i can change that later )

这是具有导致错误的行的标题.: http://pastebin.com/k3D4cg0d​​

This is the header that has the lines that results in errors.: http://pastebin.com/k3D4cg0d

这是它所引用的C文件. http://pastebin.com/Ymg1X5dg

And this is the C file it refers to.: http://pastebin.com/Ymg1X5dg

这给出了这样的错误.:

This is giving an error like this.:

/var/tmp/cc3zA0lH.s: Assembler messages: /var/tmp/cc3zA0lH.s:69: Error: bad instruction `sw $3,0(r3)',

对于其余的行,依此类推.

And so on for the rest of those lines.

推荐答案

该内联程序集存在错误:

That inline assembly is buggy:

  1. 它使用有效连接的多行字符串.如果没有\n,则全部显示在一行上.是否用分号分隔的汇编程序 accepts 语句使所有区别都存在……有些可能不会.
  2. 它指定与输入/输出约束相同的变量,而不是通常针对这种情况使用"+r"(value).
  1. It uses multi-line strings which effectively concatenate. Without \n all appears on one line. Whether your assembler accepts statements separated by semicolons makes all the difference there ... some may not.
  2. It specifies the same variable as input/output constraint instead of using "+r"(value) as ordinarily suggested for this situation.

在没有看到其余代码的情况下,并不清楚为什么内联汇编语句看起来像它的样子.就个人而言,我建议这样写:

Without seeing the rest of the code it's not quite clear why the inline assembly statement looks the way it does; Personally, I'd suggest to write it like:

asm("ror %%cl, %0" : "+r"(value) : "c"((((uintptr_t)address) & 3) << 3)));

因为在组装时几乎不需要自己进行计算. uintptr_t(来自<stdint.h>)强制转换也使该32/64位不可知.

because there's little need to do the calculation itself in assembly. The uintptr_t (from <stdint.h>) cast makes this 32/64bit agnostic as well.

如果您希望将其用于不同的 CPU但x86/x64,则显然需要有所不同...对于ARM( not Thumb2),它会是:

If you want it for a different CPU but x86 / x64, then it obviously needs to be different ... For ARM (not Thumb2), it'd be:

asm("ROR %0, %0, %1" : "+r"(value) : "r"((((uintptr_t)address) & 3) << 3)));

因为那是旋转指令的行为方式.

since that's how the rotate instruction there behaves.

编辑(添加参考):

关于此处执行的操作,此博客文章给出了一个有趣的观点-即,编译器很可能会为以下内容创建相同的输出:

Regarding the operation performed here as such, this blog post gives an interesting perspective - namely, that the compiler is quite likely to create the same output for:

(a >> shift | a << (8 * sizeof(a) - shift))

对于x86内联

asm("ror %%cl, %0" : "+r"(a) : "c"(shift))

对此进行测试:

#include <stdint.h>

int main(int argc, char **argv)
{
    unsigned int shift = (int)((((uintptr_t)argv) & 3) << 3);
    unsigned int a = argc;
#ifdef USE_ASM
    /*
     * Mark the assembly version with a "nop" instruction in output
     */
    asm("nop\n\t"
        "ror        %%cl, %0" : "+r"(a) : "c"(shift));
    return a;
#else
    return (a >> shift | a << (8 * sizeof(a) - shift));
#endif
}

编译/反汇编:

$ gcc -DUSE_ASM -O8 -c tf.c; objdump -d tf.o

tf.o:     file format elf64-x86-64

Disassembly of section .text:

0000000000000000 :
   0:   83 e6 03                and    $0x3,%esi
   3:   8d 0c f5 00 00 00 00    lea    0x0(,%rsi,8),%ecx
   a:   90                      nop
   b:   d3 cf                   ror    %cl,%edi
   d:   89 f8                   mov    %edi,%eax
   f:   c3                      retq
$ gcc -O8 -c tf.c; objdump -d tf.o

tf.o:     file format elf64-x86-64

Disassembly of section .text:

0000000000000000 :
   0:   83 e6 03                and    $0x3,%esi
   3:   8d 0c f5 00 00 00 00    lea    0x0(,%rsi,8),%ecx
   a:   d3 cf                   ror    %cl,%edi
   c:   89 f8                   mov    %edi,%eax
   e:   c3                      retq

Ergo,此内联程序是不必要的.

Ergo, this inline assembly is unnecessary.

这篇关于错误:"asm"中不可能的寄存器约束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆