问题描述
我在编译软件包时遇到问题,我不是确实是一个很好的编码器,但是我尝试自己修复它,但仍然无法编译.这是原始代码.
I've run into a problem while compiling a package around, I am notreally 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 ispart 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 whichcompiler 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:
- 它使用有效连接的多行字符串.如果没有
\n
,则全部显示在一行上.是否用分号分隔的汇编程序 accepts 语句使所有区别都存在……有些可能不会. - 它指定与输入/输出约束相同的变量,而不是通常针对这种情况使用
"+r"(value)
.
- 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. - 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"中不可能的寄存器约束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!