assemblyx86sse2

SSE2 registers in x86 assembly


I have the following code:

global _start

section .text

input:
        mov     edx, buffer_size
        mov     ecx, buffer
        mov     ebx, 0                  ; stdin
        mov     eax, 3                  ; read
        int     0x80

        mov     ecx, eax                ; number of read bytes
        mov     eax, 0                  ; clear eax
        mov     ebx, 10
        lea     esi, [buffer]

convert:
        mov     edx, 0
        mov     dl, [esi]
        sub     dl, '0'
        push    edx
        mul     ebx                     ; edx = eax * ebx
        pop     edx
        add     eax, edx                ; store result in eax
        inc     esi
        dec     ecx
        cmp     ecx, 1                  ; conversion to int finished
        jnz     convert

        xorpd   xmm0, xmm0
        movups  xmm0, [eax]             ; move number to SSE2 register
        mov     ecx, 1
        movups  xmm2, [ecx]
        xorpd   xmm1, xmm1              ; clear xmm1
        movups  xmm1, xmm2

factorial:
        mulpd   xmm1, xmm0              ; result in xmm1
        subpd   xmm0, xmm2
        jnz     factorial


Basically, I take number from user and then I want to calculate factorial of this number using SSE2. The "factorial" part is not done yet, I only wanted to check if those registers get the right value. So the thing is I get segmentation fault when I try to movups xmm0, [eax] hence my question is what is the proper way to transfer this number to sse2 register? I can't find any good source to learn how to deal with SSE2, I would appreciate any tips. I'm working on Linux.


Solution

  • movups xmm0, [eax] loads 16 bytes from the address in eax and stores them into xmm0. But: in your code, eax seems to contain a value, not an address. Are you sure you want to interpret eax as an address and load from memory? The same applies to your second movups xmm0, [ecx]

    If you want to move the value as an integer into xmm0, use movd. If you want to convert it into a single precision float, use cvtsi2ss xmm0, eax. If you want to convert it to a double precision float, use cvtsi2sd xmm0, eax.

    For a good SSE reference, refer to the Intel Intrinsics Guide. Also check out the Intel Software Development Manuals. But before that, you should get basics down such as [...] denoting memory operands and what that means. If you don't understand that, you won't have any chance at mastering assembly programming. The manual for your assembler should have some details on that.