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.
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.