我的 asm 汇编代码
中有以下部分"LOOP%=:\n\t"
"movapd (%%eax), %%xmm4\n\t"
"addl $32, %%eax\n\t"
"movsd (%%edx), %%xmm5\n\t"
"addl $16, %%edx\n\t"
"movapd %%xmm4, %%xmm6\n\t"
"subl $1, %%ecx\n\t"
"unpcklpd %%xmm5, %%xmm5\n\t"
"testl %%ecx, %%ecx\n\t"
"mulpd %%xmm5, %%xmm6\n\t"
"movsd -8(%%edx), %%xmm7\n\t"
"addpd %%xmm6, %%xmm0\n\t"
"movapd -16(%%eax), %%xmm6\n\t"
"unpcklpd %%xmm7, %%xmm7\n\t"
"mulpd %%xmm6, %%xmm5\n\t"
"addpd %%xmm5, %%xmm1\n\t"
"mulpd %%xmm7, %%xmm4\n\t"
"addpd %%xmm4, %%xmm2\n\t"
"mulpd %%xmm6, %%xmm7\n\t"
"addpd %%xmm7, %%xmm3\n\t"
"jne LOOP%=\n\t" */
此代码保存在%ecx a"循环索引"中,同时扫描两个(double *)数组A和B,使用SSE2执行某些计算。两个阵列都已对齐到64Bytes(与高速缓存行对齐,因此满足SSE的16Byte对齐要求)。 %eax持有"指针"数组A和" edx"持有一个"指针"到阵列B.它运行正常,没有内存读取错误。我想知道为什么要做
"movapd (%%eax), %%xmm4\n\t"
"addl $32, %%eax\n\t"
"movsd (%%edx), %%xmm5\n\t"
"addl $16, %%edx\n\t"
......
"movsd -8(%%edx), %%xmm7\n\t"
......
"movapd -16(%%eax), %%xmm6\n\t"
......
所以我将初始版本更改为
"LOOP%=:\n\t"
"movapd (%%eax), %%xmm4\n\t"
"movsd (%%edx), %%xmm5\n\t"
"movapd %%xmm4, %%xmm6\n\t"
"subl $1, %%ecx\n\t"
"unpcklpd %%xmm5, %%xmm5\n\t"
"testl %%ecx, %%ecx\n\t"
"mulpd %%xmm5, %%xmm6\n\t"
"movsd 8(%%edx), %%xmm7\n\t"
"addl $16, %%edx\n\t"
"addpd %%xmm6, %%xmm0\n\t"
"movapd 16(%%eax), %%xmm6\n\t"
"addl $32, %%eax\n\t"
"unpcklpd %%xmm7, %%xmm7\n\t"
"mulpd %%xmm6, %%xmm5\n\t"
"addpd %%xmm5, %%xmm1\n\t"
"mulpd %%xmm7, %%xmm4\n\t"
"addpd %%xmm4, %%xmm2\n\t"
"mulpd %%xmm6, %%xmm7\n\t"
"addpd %%xmm7, %%xmm3\n\t"
"jne LOOP%=\n\t"
但是我因无效读取而遇到分段错误。
这对我来说很有趣。为什么呢?
答案 0 :(得分:2)
这是原因:
"testl %%ecx, %%ecx\n\t"
此测试的结果用于此代码最后的循环条件。通过移动添加操作,您可以覆盖条件的标志,因此它始终满足并永远运行直到离开内存。