Fasm 汇编语言和 SSE指令
用fasm汇编语言编译器编译测试代码,编译正常,运行有异常。
SSE 指令和 MMX指令的区别是寄存器不一样,MMX是,mm0-mm7,SSE是XMM0-XMM7,SSE2是 XMM8-XMM15,扩展的是XMM16-XMM31
proc fir input:dword,out:dword,coeff:dword,count:dword pxor xmm0, xmm0 xor ecx, ecx mov eax,input1 mov ebx,coeff1 inner_loop: movups xmm1,[eax+ecx] mulss xmm1,[ebx+4*ecx] addps xmm0, xmm1 pxor xmm0, xmm0 xor ecx, ecx mov eax,input1 mov ebx,coeff1 movups xmm1,[eax+ecx] ; movaps xmm3, xmm1 mulss xmm1,[ebx+4*ecx] addps xmm0, xmm1 movups xmm1,[eax+ecx+4] mulss xmm1,[ebx+4*ecx+16] addps xmm0, xmm1 movups xmm2,[eax+ecx+16] movups xmm1, xmm2 palignr xmm2, xmm3, 4 mulss xmm2,[ebx+4*ecx+16] addps xmm0, xmm2 movups xmm1,[eax+ecx+8] mulss xmm1,[ebx+4*ecx+32] addps xmm0, xmm1 movups xmm2, xmm1 palignr xmm2, xmm3, 8 mulss xmm2,[ebx+4*ecx+32] addps xmm0, xmm2 movups xmm1,[eax+ecx+12] mulss xmm1,[ebx+4*ecx+48] addps xmm0, xmm1 add ecx, 16 cmp ecx, 4*TAP jl inner_loop mov eax,out1 movups [eax], xmm1 pxor xmm0, xmm0 xor ecx, ecx mov eax, input1 mov ebx, coeff1 inner_loop1: movups xmm1, [eax+ecx] movups xmm3, xmm1 mulss xmm1, [ebx+4*ecx] addps xmm0, xmm1 movups xmm2, [eax+ecx+16] movups xmm1, xmm2 palignr xmm2, xmm3, 4 mulss xmm2, [ebx+4*ecx+16] addps xmm0, xmm2 movups xmm2, xmm1 palignr xmm2, xmm3, 8 mulss xmm2, [ebx+4*ecx+32] addps xmm0, xmm2 movups xmm2, xmm1 palignr xmm2, xmm3, 12 mulss xmm2, [ebx+4*ecx+48] addps xmm0, xmm2 add ecx, 16 cmp ecx, 4*TAP jl inner_loop1 mov eax, out1 movups [eax], xmm0 p_exit: ret endp
这是一段优化代码
section '.data' data readable writeable TAP equ 1 flags dd ? caption db '测试',0 message db '这是一个测试',0 input1 dq 1111,2222,3333,4444,5555,6666,7777,8888,9999,0000,0 out1 dd 10 dup(?) coeff1 dq 0000,9999,8888,7777,6666,5555,4444,3333,2222,1111,0 count1 dw 10
数据测试是这个数据,先的程序不是这样子的。
源代码在intel 代码优化白皮书中。
源代码中指令是 movaps
在fasm 中 数据最长为 dq,dt 也就是8字节,10字节。没有xmm的16字节 128位字节的定义。
如果是有符号的 movaps 读数据段,会抛出一个异常,改为movups 就正常
mulps 改为mulss 原理一样。是fasm 生成的 exe文件,或者是 win10 的数据保护产生的指令异常。绕过就可以了。