我在编译程序包时遇到了问题,我不是 真的是一个很好的程序员,但我试着为自己修复它,它仍然无法编译。 这是原始代码。:
#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)
这就是我试图让它看起来的方式。:
#ifdef __GNUC__
asm ("and $3 %%ecx,shl $3 %%ecx,ror %%cl, %0" : "=r" (value): "r" (value), "c" (address));
#else
但是,它不会起作用。这是一个gba模拟器,才有人问,VBA,这是 GBAinline.h的一部分。这个汇编程序让我疯了。
编辑:上面的问题处理得很好,我只是没注意哪个 我正在使用的编译器。 但是现在我从头文件中得到了这个代码的错误,我把它放在了pastebin上, 保持这里的东西更整洁...(对不起,如果这是错误的,我可以稍后改变)
这是包含导致错误的行的标题: http://pastebin.com/k3D4cg0d
这是它引用的C文件: http://pastebin.com/Ymg1X5dg
这就是这样的错误。:
/var/tmp/cc3zA0lH.s: Assembler messages: /var/tmp/cc3zA0lH.s:69: Error: bad instruction `sw $3,0(r3)',
等等其余部分。
答案 0 :(得分:1)
内联装配是错误的:
\n
的所有内容都出现在一行中。无论你的汇编程序接受以分号分隔的语句,都会产生不同......有些可能没有。"+r"(value)
。在没有看到其余代码的情况下,为什么内联汇编语句看起来像它的方式并不十分清楚;就个人而言,我建议写它:
asm("ror %%cl, %0" : "+r"(value) : "c"((((uintptr_t)address) & 3) << 3)));
因为在装配中几乎不需要进行计算。 uintptr_t
(来自<stdint.h>
)演员也使这个32 / 64bit不可知。
修改强>
如果你想要一个不同的 CPU而不是x86 / x64,那么它显然需要不同......对于ARM(不是 Thumb2),它是'是:
asm("ROR %0, %0, %1" : "+r"(value) : "r"((((uintptr_t)address) & 3) << 3)));
因为那是旋转指令的行为。
编辑(添加参考):
关于这里执行的操作,this blog post提供了一个有趣的视角 - 即编译器很可能为以下内容创建相同的输出:
(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
因此,这种内联汇编是不必要的。