使用SSE执行简单的算术运算(IA32汇编)

时间:2013-11-08 15:57:39

标签: assembly x86 sse

在我的大学,我们刚刚被介绍到IA32 SSE。我想要做的是添加两个向量(它们称之为“打包值”,这意味着向量包含四个32位单精度浮点数。一个verctor的大小是128位。)这是我正在尝试的要做:

%xmm0      | 5.5 | 1.2 | 2.4 | 7.0 |
%xmm1      | 3.0 | 1.5 | 3.5 | 2.2 |
              |     |     |     |
              +     +     +     +
              |     |     |     |
              V     V     V     V
%xmm0      | 8.5 | 2.7 | 5.9 | 9.2 |

然而,在幻灯片中,他们只显示以下代码片段,我根本无法开始工作:

# %eax and %ebx contain the addresses of the two vectors that are to be added
movups (%eax), %xmm0
movups (%ebx), %xmm1
addps %xmm1, %xmm0
movups %xmm0, result

这提出了两个问题:

1。我如何首先创建这些向量,如何使%eax和%ebx指向它们?

2。如何打印结果以检查操作是否成功?

这是我尝试过的。以下代码在运行时编译并且不会崩溃。但是,根本没有输出...:/

.data
    x0: .float 7.0
    x1: .float 2.4
    x2: .float 1.2
    x3: .float 5.5
    y0: .float 2.2
    y1: .float 3.5
    y2: .float 1.5
    y3: .float 3.0
    result: .float 0
    intout: .string "Result: %f.\n"

.text
.global main

main:
    pushl x3
    pushl x2
    pushl x1
    pushl x0
    movl %esp, %eax
    pushl y3
    pushl y2
    pushl y1
    pushl y0
    movl %esp, %ebx

    movups (%eax), %xmm0
    movups (%ebx), %xmm1
    addps %xmm1, %xmm0
    movups %xmm0, result

    pushl result
    pushl $intout
    call printf
    addl $40, %esp
    movl $1, %eax
    int $0x80

2 个答案:

答案 0 :(得分:2)

您似乎对如何在多个数据项上声明标签以及如何将标签加载到寄存器感到困惑。标签只是一个地址 - 内存中的一个点 - 没有任何大小或与之相关的任何其他内容。标签后的内容在内存中的连续地址中。因此,您将一个引用向量的标签声明为:

x:
    .float 7.0
    .float 2.4
    .float 1.2
    .float 5.5

现在您可以通过简单的移动将该地址加载到寄存器中,然后使用寄存器加载向量:

    movl   $x, %eax
    movups (%eax), %xmm0

或者,您可以直接从标签

加载
    movups x, %xmm0

答案 1 :(得分:1)

%f的{​​{1}}说明符表示 double 参数,而不是float参数。因此,您需要转换结果向量中的单浮点数并将它们移动到堆栈中。我就是这样做的:

printf