(在C内联汇编)汇编的消息:错误:未知的伪操作: [英] (inline assembly in C) Assembler messages: Error: unknown pseudo-op:
问题描述
我写了一个简短C包装功能,为的 ASM 的内联汇编,如下图所示。组装code由一个while循环,计算使用SSE2几个向量的点积。我在x86上的Ubuntu 14.04使用GCC 4.8.4。下面code可以在
I have written a short C "wrapper" function for an asm inline assembly, as below. The assembly code consists of a while loop, computing several vector dot product using SSE2. I am using GCC 4.8.4 on Ubuntu 14.04 on an x86. The following code can be assembled "without problem" under
gcc的-fpic -O2 -msse2 -S foo.c的
gcc -fpic -O2 -msse2 -S foo.c
但是当我做
GCC -c foo.s
gcc -c foo.s
错误被触发:
foo.c的:汇编信息:结果
foo.c的:2:错误:未知的伪操作:`.while5
我检查了汇编输出中foo.s,发现一些奇怪的。
I checked the assembler ouput "foo.s" and found something strange.
C文件foo.c的
#include <emmintrin.h>
void foo (int kk, double *A, double *B, double *ALPHA, double *C, int ldc) {
asm("movl %0, %%ecx\n\t" /* kk -> %ecx */
"movl %3, %%eax\n\t" /* A -> %eax */
"movl %4, %%edx\n\t" /* B -> %edx */
/* a while-loop */
".while%=\n\t"
"movsd (%%edx), %%xmm5\n\t"
"unpcklpd %%xmm5, %%xmm5\n\t"
"movapd %%xmm5, %%xmm6\n\t"
"movapd (%%eax), %%xmm4\n\t"
"mulpd %%xmm4, %%xmm6\n\t"
"movapd 16(%%eax), %%xmm7\n\t"
"addl $32, %%eax\n\t"
"addpd %%xmm6, %%xmm0\n\t"
"mulpd %%xmm7, %%xmm5\n\t"
"addpd %%xmm5, %%xmm1\n\t"
"movsd 8(%%edx), %%xmm6\n\t"
"addl $16, %%edx\n\t"
"unpcklpd %%xmm6, %%xmm6\n\t"
"mulpd %%xmm6, %%xmm4\n\t"
"addpd %%xmm4, %%xmm2\n\t"
"mulpd %%xmm6, %%xmm7\n\t"
"addpd %%xmm7, %%xmm3\n\t"
"subl $1, %%ecx\n\t" /* kk-- */
"testl %%ecx, %%ecx\n\t" /* kk = 0 ? */
"jne .while%=\n\t"
/* other input operands passing */
"movl %5, %%ecx\n\t" /* C -> %ecx */
"movl %1, %%eax\n\t" /* ALPHA -> %eax, then C0 -> %eax */
"movl %2, %%edx\n\t" /* ldc -> %edx */
/* write-back */
"movsd (%%eax), %%xmm7\n\t"
"unpcklpd %%xmm7, %%xmm7\n\t"
"leal (%%ecx,%%edx,8), %%eax\n\t" /* C0=C+ldc */
"mulpd %%xmm7, %%xmm0\n\t"
"addpd (%%ecx), %%xmm0\n\t"
"movapd %%xmm0, (%%ecx)\n\t"
"mulpd %%xmm7, %%xmm2\n\t"
"addpd (%%eax), %%xmm2\n\t"
"movapd %%xmm2, (%%eax)\n\t"
"mulpd %%xmm7, %%xmm1\n\t"
"addpd 16(%%ecx), %%xmm1\n\t"
"movapd %%xmm1, 16(%%ecx)\n\t"
"mulpd %%xmm7, %%xmm3\n\t"
"addpd 16(%%eax), %%xmm3\n\t"
"movapd %%xmm3, 16(%%eax)\n\t"
: /* no output operands */
: "m"(kk), "m"(ALPHA), "m"(ldc), "m"(A), "m"(B), "m"(C) /* input operands */
: "eax", "edx", "ecx", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" /* clobbers */ );
}
汇编输出(while循环看起来很奇怪!)
assembler output (the while-loop looks odd!)
.LFB503:
.cfi_startproc
#APP
# 4 "foo.c" 1
movl 4(%esp), %ecx
movl 8(%esp), %eax
movl 12(%esp), %edx
.while5
movsd (%edx), %xmm5
unpcklpd %xmm5, %xmm5
movapd %xmm5, %xmm6
movapd (%eax), %xmm4
mulpd %xmm4, %xmm6
movapd 16(%eax), %xmm7
addl $32, %eax
addpd %xmm6, %xmm0
mulpd %xmm7, %xmm5
addpd %xmm5, %xmm1
movsd 8(%edx), %xmm6
addl $16, %edx
unpcklpd %xmm6, %xmm6
mulpd %xmm6, %xmm4
addpd %xmm4, %xmm2
mulpd %xmm6, %xmm7
addpd %xmm7, %xmm3
subl $1, %ecx
testl %ecx, %ecx
jne .while5
movl 20(%esp), %ecx
movl 16(%esp), %eax
movl 24(%esp), %edx
movsd (%eax), %xmm7
unpcklpd %xmm7, %xmm7
leal (%ecx,%edx,8), %eax
mulpd %xmm7, %xmm0
addpd (%ecx), %xmm0
movapd %xmm0, (%ecx)
mulpd %xmm7, %xmm2
addpd (%eax), %xmm2
movapd %xmm2, (%eax)
mulpd %xmm7, %xmm1
addpd 16(%ecx), %xmm1
movapd %xmm1, 16(%ecx)
mulpd %xmm7, %xmm3
addpd 16(%eax), %xmm3
movapd %xmm3, 16(%eax)
# 0 "" 2
#NO_APP
ret
.cfi_endproc
任何人都可以仔细查阅我发生了什么事?我不认为这是我的编译器的问题。一定有什么地方错了我的code。 THX!
Can anyone kindly refer to me what has happened? I don't think it is my compiler's problem. There must be something wrong with my code. Thx!
推荐答案
由于您的。而
没有被定义为一个标签,它被看作是一个[子虚乌有]伪操作。
Because your .while
is not defined as a label, it's being seen as a [non-existent] pseudo-op.
修改
".while%=\n\t"
进入:
".while%=:\n\t"
更新:
根据您的要求。
一个伪操作,是不符合指令的一个装配台指令[用于术语。
A "pseudo-op" is [terminology for] an assember directive that doesn't correspond to an instruction.
一些例子:
.globl主
来指定该主
标签是一个全局变量。
.globl main
to specify that the main
label is a global variable.
的.text
指定其后的内容应放置在文本段(同样为。数据
)。
.text
to specify that what follows should be placed in the "text" segment (likewise for .data
).
的。
preFIX是[通常]保留伪欢声笑语。这就是为什么你得到了错误:未知的伪操作:
的消息
The .
prefix is [generally] reserved for pseudo ops. That's why you got the Error: unknown pseudo-op:
message.
如果你做了,而%= \\ n \\ t的
而不是[仍然是错误的,因为没有:
来表示一个标号],你会得到不同的信息:错误:没有这样的指令:
If you had done "while%=\n\t"
instead [still wrong because there was no :
to denote a label], you would have gotten a different message: Error: no such instruction:
这篇关于(在C内联汇编)汇编的消息:错误:未知的伪操作:的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!