##Wrong increment## First, there is a bug in your main loop. This line: add ebx, 1 should be: add ebx, 4 because you are operating on 4 floats at a time. Right now, you are doing array elements [0..3] following by [1..4]. On my computer the program crashed because it had a problem doing an unaligned load. ##Simplify divide by 4## This part where you divide ecx by 4: push eax mov edx, 0 mov eax, ecx mov ebx, 4 div ebx mov ecx, eax ; ecx becomes the counter for the packed iterations pop eax can be simplified to this: mov edx, ecx and edx, 3 shr ecx, 2 Explanation: `shr` is the shift right instruction. When you shift right by 2 it is the same thing as dividing by 4. To get the remainder of something divided by 4, you just need to `and` that number with 3. C equivalent code: remainder = length & 3; length >>= 2; ##Remove one jump from main loop## Your main loop: .loopP: movaps xmm1, [esi+ebx*4] movaps xmm2, [edi+ebx*4] subps xmm1, xmm2 mulps xmm1, xmm1 dec ecx haddps xmm1, xmm1 haddps xmm1, xmm1 addps xmm0, xmm1 jz .loopC add ebx, 4 jmp .loopP .loopC cmp edx, 0 je .endD Can be rewritten to remove one of the jumps at the end: .loopP: movaps xmm1, [esi+ebx*4] movaps xmm2, [edi+ebx*4] subps xmm1, xmm2 add ebx, 4 mulps xmm1, xmm1 dec ecx haddps xmm1, xmm1 haddps xmm1, xmm1 addps xmm0, xmm1 jnz .loopP cmp edx, 0 je .endD sub ebx, 4 ##Loading the mask## The part where you do a chain of compares to load one of three masks: .dU1: cmp edx, 1 jne .dU2 movaps xmm7, [mask1] jmp .dU .dU2: cmp edx, 2 jne .dU3 movaps xmm7, [mask2] jmp .dU .dU3: movaps xmm7, [mask3] can be simplified to this: .dU1: shl edx, 4 movaps xmm7, [mask1 + edx - 16] Explanation: Your masks are located in memory in consecutive order like an array of 128 bit values. So you can load them by index. Note that `edx` is 1..3 here. The `shl` instruction is shift left, and shifting left by 4 multiplies `edx` by 16. Then we load from mask1 + edx - 16. The minus 16 is because `edx` started at one instead of zero. Equivalent C code is something like this: uint8_t mask1[48] = { /* values */ }; mask128 = *(__m128 *) &mask1[(remainder<<4)-16]; ##Stack push/pop## I'm not sure if this is part of your calling convention, but your prologue and epilogue have extraneous instructions: push ebp mov ebp, esp sub esp, 4 push ebx push esi push edi pop edi pop esi pop ebx mov esp, ebp pop ebp ret Could be changed to: push ebp mov ebp, esp push ebx push esi push edi pop edi pop esi pop ebx pop ebp ret Furthermore, you are not utilizing `eax`. If you used `eax` instead of `ebx` everywhere in your function, you wouldn't have to save `ebx` because you wouldn't ever use it. You can load the result pointer into `eax` at the very end instead of at the beginning. ##Comments## In general I liked all your comments. The one thing I thought you could add a comment for was that this double instruction: haddps xmm1, xmm1 haddps xmm1, xmm1 adds all 4 floats in `xmm1` into the first float in `xmm1`. I wasn't familiar with the `haddps` instruction and I initially thought you made a typo (I thought a single `haddps` would do the whole job). ##Alignment required## I was able to use the function successfully, but when I modified my `main()`, the program crashed. The difference was that my modification caused the arrays I passed to `distance()` to be not aligned to 16 bytes. Since the `movaps` instruction expects 128 bit alignment, the arrays passed in need to have 128 bit alignment. I think you should switch to the `movups` instruction which handles unaligned floats.