x86 汇编中的 SSE2 寄存器

SSE2 registers in x86 assembly

我有以下代码:

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


基本上,我从用户那里获取数字,然后我想使用 SSE2 计算这个数字的阶乘。 “阶乘”部分尚未完成,我只想检查这些寄存器是否获得正确的值。所以问题是当我尝试 movups xmm0, [eax] 时出现分段错误因此我的问题是将此数字传输到 sse2 寄存器的正确方法是什么?我找不到任何好的资源来学习如何处理 SSE2,我将不胜感激任何提示。我正在研究 Linux。

movups xmm0, [eax] 从 eax 中的地址加载 16 个字节并将它们存储到 xmm0 中。但是:在您的代码中, eax 似乎包含一个值,而不是地址。您确定要将 eax 解释为地址并从内存中加载吗?这同样适用于您的第二个 movups xmm0, [ecx]

如果要将值作为整数移动到 xmm0,请使用 movd。如果要将其转换为单精度浮点数,请使用 cvtsi2ss xmm0, eax。如果要将其转换为双精度浮点数,请使用 cvtsi2sd xmm0, eax.

要获得良好的 SSE 参考,请参阅 Intel Intrinsics Guide. Also check out the Intel Software Development Manuals。但在此之前,您应该了解基础知识,例如 [...] 表示内存操作数及其含义。如果你不明白这一点,你将没有任何机会掌握汇编编程。您的汇编程序手册应该有一些详细信息。