3

私の大学では、IA32 SSE を紹介されたばかりです。私がやろうとしているのは、2 つのベクトルを追加することです (彼らはそれを「パック値」と呼びます。これは、ベクトルに 4 つの 32 ビット単精度浮動小数点数が含まれていることを意味します。1 つのバークターのサイズは 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

これにより、次の 2 つの疑問が生じます。

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
4

2 に答える 2

2

複数のデータ項目でラベルを宣言する方法と、ラベルをレジスタにロードする方法について混乱しているようです。ラベルは単なるアドレス (メモリ内のポイント) であり、サイズやその他の関連付けはありません。ラベルの後のものは、メモリ内の連続したアドレスにあります。したがって、ベクトルを参照するラベルを次のように宣言します。

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

これで、単純な移動でそのアドレスをレジスタにロードし、レジスタを使用してベクトルをロードできます。

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

または、ラベルから直接ロードすることもできます

    movups x, %xmm0
于 2013-11-08T17:07:08.873 に答える
2

%f指定子は、float 引数ではなくdoubleprintf引数を示します。そのため、結果ベクトル内のシングルフロートを変換してスタックに移動する必要があります。これは私がそれを行う方法です:

.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
于 2013-11-08T17:18:36.183 に答える