2013-09-29 9 views
6

私はアセンブリ時に合計noobですが、何が起こっているのかちょっと調べてみてください。とにかく、私は非常に簡単な関数を書いた:xorl%eax、x86_64アセンブリコード内の%eax(gccによって生成)

void multA(double *x,long size) 
{ 
    long i; 
    for(i=0; i<size; ++i){ 
    x[i] = 2.4*x[i]; 
    } 
} 

私はそれをコンパイル:

gcc -S -m64 -O2 fun.c 

そして、私はこれを取得:

.file "fun.c" 
    .text 
    .p2align 4,,15 
    .globl multA 
    .type multA, @function 
multA: 
.LFB34: 
    .cfi_startproc 
    testq %rsi, %rsi 
    jle .L1 
    movsd .LC0(%rip), %xmm1 
    xorl %eax, %eax 
    .p2align 4,,10 
    .p2align 3 
.L3: 
    movsd (%rdi,%rax,8), %xmm0 
    mulsd %xmm1, %xmm0 
    movsd %xmm0, (%rdi,%rax,8) 
    addq $1, %rax 
    cmpq %rsi, %rax 
    jne .L3 
.L1: 
    rep 
    ret 
    .cfi_endproc 
.LFE34: 
    .size multA, .-multA 
    .section .rodata.cst8,"aM",@progbits,8 
    .align 8 
.LC0: 
    .long 858993459 
    .long 1073951539 
    .ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3" 
    .section .note.GNU-stack,"",@progbits 

アセンブリ出力は(主に)私には理にかなっていると行番号xorl %eax, %eaxを除きます。グーグルでは、この目的は単に%eaxを0に設定することであることがわかります。この場合、これは私のイテレータlong i;に対応しています。

ただし、私が間違っていない限り、%eaxは32ビットのレジスタです。だから、これは実際にはxorq %rax, %raxでなければならないと思います。特にこれは64ビットのintを保持しているからです。さらに、コードのさらに下には、実際には%raxというレジスタを使用して反復処理を行います。これは決してxorl %eax %eaxの外部で初期化されることはなく、レジスタの下位32ビットのみをゼロにするようです。

何か不足していますか?

また、好奇心の理由から、なぜそこに2つの.longの定数がありますか?最初の1つは858993459で、ダブル浮動小数点表現2.4と同じですが、2番目の数字が何であるか、それがなぜ存在するのかわかりません。

+0

は、ご使用のプラットフォーム上で ''のsizeof(長い)とは何ですか? –

+0

@KerrekSBああ。私は、ごめんなさい。 –

+0

sizeof(long)は8 – mrip

答えて

8

私はこれの目的は、ゼロ

Yesに%eaxに設定するだけであることを収集します。

これは私のイテレータlong i;に対応します。

いいえiは、宣言で未初期化です。厳密に言えば、その操作はforループの式i = 0に対応します。

ただし、私が間違っていない限り、%eaxは32ビットレジスタです。だから、これは実際にはxorq%rax、%rax、特にこれが64ビットのlong intを保持しているからです。

しかし、レジスタの下位ダブルワードをクリアすると、レジスタ全体がクリアされます。これは直感的ではありませんが、暗黙のものです。

+1

ありがとうございます。私はそれが事実であるに違いないと思ったが、私はそれがどこにでも書かれているのを見つけることができなかった。私が言ったように、私は完全な騒ぎです。 – mrip

+1

今日何か新しいことを学んだが、EAXがRAXをクリアすることは分からなかった。しかし、「下位語をクリアする」が正しい方法であるかどうかは疑問ですが、AMD64アーキテクチャでは64ビットのワードサイズではありませんか? – us2012

+2

@ us2012 "word size"の通常の定義は単にIntelによって無視されます。単語は常に16ビットです。 32 = dword、64 = qword。 – harold

2

ちょうど第二の部分に答えるために:.long 32ビットを意味し、2つの積分定数サイドバイサイド二重2.4のIEEE-754の表現を形成:

Dec: 1073951539 858993459 
Hex: 0x40033333 0x33333333 

    400 3333333333333 
    S+E Mantissa 

の指数が1023によって相殺されます実際の指数は、0x400   − =   1の仮数のリーディング "1" であるので、それは2   ×   0B1をですので、暗示されています。001100110011は...(あなたは3月15日、この定期的な拡大、すなわち0.2を認識。案の定、2   ×   1.2   =   2.4。)

+0

Aha。ありがとう。それは完璧な意味合いがあります。 – mrip

+1

ええ。なぜなら私は64ビット長の 'double '型に注意を払わないからです。 +1。 –

+1

@ H2CO3:あなたはそれがほとんど正しいと思っていますが、指数部の大きさはあなたに謝っているはずです:-) –

関連する問題