assembly - 使用 SSE(IA32 程序集)执行简单的算术运算

标签 assembly x86 sse

在我的大学里,我们刚刚接触到 IA32 SSE。我想做的是添加两个向量(他们称之为“打包值”,这意味着该向量包含四个 32 位单精度 float 。一个 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

最佳答案

printf%f 说明符表示double 参数,而不是float 参数。因此,您需要隐藏结果向量中的单 float 并将它们移动到堆栈中。我会这样做:

.section ".rodata"
fmt:    .string "%f %f %f %f\n"
        .align 16
vec1:
        .float 7.0
        .float 2.4
        .float 1.2
        .float 5.5
vec2:
        .float 2.2
        .float 3.5
        .float 1.5
        .float 3.0    

.data
        .align 16
result:
        .float 0.0
        .float 0.0
        .float 0.0
        .float 0.0

        .text
.globl main
main:
        movl    %esp, %ebp

        andl    $-16, %esp      # align stack

        movaps  vec1, %xmm0
        movaps  vec2, %xmm1
        addps   %xmm1, %xmm0
        movaps  %xmm0, result

        subl    $36, %esp
        movl    $fmt, (%esp)
        movss   result, %xmm0
        cvtss2sd %xmm0, %xmm0
        movsd   %xmm0, 4(%esp)
        movss   result+4, %xmm0
        cvtss2sd %xmm0, %xmm0
        movsd   %xmm0, 12(%esp)
        movss   result+8, %xmm0
        cvtss2sd %xmm0, %xmm0
        movsd   %xmm0, 20(%esp)
        movss   result+12, %xmm0
        cvtss2sd %xmm0, %xmm0
        movsd   %xmm0, 28(%esp)
        call    printf
        addl    $36, %esp

        xorl    %eax, %eax
        movl    %ebp, %esp
        ret

关于assembly - 使用 SSE(IA32 程序集)执行简单的算术运算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19863309/

相关文章:

c++ - Intel cpu 上的 SIMD 前缀和

c - 为什么一个字节的大小必须是8位?

assembly - 当使用多个数据库声明时,NASM 编译 x86_64 ASM 标签地址在 Mach-O 中减少 256 个字节?

assembly - 选择 EFLAGS 位的概率

c - 从 RGB 到 BGRA 的快速矢量化转换

c - asm 中的寄存器数组

c - 如何从汇编指令到 C 代码

assembly - 键盘箭头的扫描码是什么? (右,左,下,上)

string - 在 x86 程序集中附加两个字符串

x86 - 如何转储 gdb 中的所有 XMM 寄存器?