2011-11-15 22 views
1

基本的に、アセンブリで浮動小数点演算を使用して行列にベクトルを乗算するだけです。AT&T構文の浮動小数点演算

私の最初のドラフトでは次のようになります。残念ながら

.data 
    mat: .float 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 
    vek: .float 1.0, 2.0, 3.0 
    res: .float 0.0, 0.0 
    .text 
    .globl main 
    main: 
    ; here goes the magic 
    call exit 

、私が試したすべてが動作しません。私は基本的な算術演算(faddp、fmulpなど)を行う方法を知っていますが、それでも効率的に格納することはできません。 fstplはまったく動作していないようです。

FPUコマンドの使い方と、計算結果をレジスタに保存する方法は、誰にでも分かりますか?事前に

おかげで、

+2

(レガシー) 'x87'命令を使用する必要があるのでしょうか? SSEははるかに使いやすくなっています。 –

答えて

2

はその後したり、独自のコードのためのテンプレートとして使用されるようことを使用するか、その後、アセンブラソースを生成するためにgcc -Sを使用し、それをテスト、最初のCでそれを実装します。

など。ここではCコードの実装、mat_vec.cです:

#include <stdio.h> 

int main(void) 
{ 
    // note: use "volatile" qualifier for input data otherwise gcc will 
    //  just optimise all the arithmetic away... 
    volatile float mat[2][3] = { { 1.0f, 2.0f, 3.0f }, { 4.0f, 5.0f, 6.0f } }; 
    volatile float vek[3] = { 1.0f, 2.0f, 3.0f }; 
    float res[2] = { 0.0f, 0.0f }; 

    res[0] = mat[0][0] * vek[0] + mat[0][1] * vek[1] + mat[0][2] * vek[2]; 
    res[1] = mat[1][0] * vek[0] + mat[1][1] * vek[1] + mat[1][2] * vek[2]; 

    printf("res = { %g, %g }\n", res[0], res[1]); 

    return 0; 
} 

はのは、それが動作することを確認してみましょう:

$ gcc -Wall -Os -m32 -march=i686 mat_vec.c -o mat_vec 
$ ./mat_vec 
res = { 14, 32 } 
$ 

はよさそうだ、そうのは、アセンブラソースを生成してみましょう:

$ gcc -Wall -Os -m32 -march=i686 -S mat_vec.c -o mat_vec.S 
$ cat mat_vec.S 
    .cstring 
LC6: 
    .ascii "res = { %g, %g }\12\0" 
    .text 
.globl _main 
_main: 
    pushl %ebp 
    movl $0x40000000, %ecx 
    movl %esp, %ebp 
    movl $0x40400000, %edx 
    pushl %esi 
    movl $0x40800000, %eax 
    pushl %ebx 
    movl $0x3f800000, %esi 
    subl $96, %esp 
    movl %esi, -44(%ebp) 
    movl %ecx, -40(%ebp) 
    movl %edx, -36(%ebp) 
    movl %eax, -32(%ebp) 
    movl $0x40a00000, %eax 
    movl %eax, -28(%ebp) 
    movl $0x40c00000, %eax 
    movl %eax, -24(%ebp) 
    movl %esi, -20(%ebp) 
    movl %ecx, -16(%ebp) 
    movl %edx, -12(%ebp) 
    flds -44(%ebp) 
    flds -20(%ebp) 
    fstps -72(%ebp) 
    flds -40(%ebp) 
    flds -16(%ebp) 
    fstps -68(%ebp) 
    flds -36(%ebp) 
    fstps -64(%ebp) 
    flds -12(%ebp) 
    fstps -60(%ebp) 
    flds -32(%ebp) 
    flds -20(%ebp) 
    flds -28(%ebp) 
    flds -16(%ebp) 
    fxch %st(3) 
    fmulp %st, %st(2) 
    flds -24(%ebp) 
    flds -12(%ebp) 
    fxch %st(2) 
    fmulp %st, %st(4) 
    call L3 
"L00000000001$pb": 
L3: 
    popl %ebx 
    fmulp %st, %st(1) 
    fxch %st(3) 
    fmuls -68(%ebp) 
    fxch %st(1) 
    faddp %st, %st(2) 
    fxch %st(3) 
    fmuls -72(%ebp) 
    fxch %st(1) 
    faddp %st, %st(2) 
    fxch %st(1) 
    leal LC6-"L00000000001$pb"(%ebx), %eax 
    fstpl 12(%esp) 
    flds -64(%ebp) 
    fmuls -60(%ebp) 
    fxch %st(1) 
    faddp %st, %st(2) 
    faddp %st, %st(1) 
    fstpl 4(%esp) 
    movl %eax, (%esp) 
    call L_printf$stub 
    addl $96, %esp 
    xorl %eax, %eax 
    popl %ebx 
    popl %esi 
    leave 
    ret 
    .section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5 
L_printf$stub: 
    .indirect_symbol _printf 
    hlt ; hlt ; hlt ; hlt ; hlt 
    .subsections_via_symbols 

あなたがしている部分興味があるのはラベルL3の直前です。

関連する問題