2016-09-05 10 views
1

最近、fp番号の小さなプログラムを書いていました。 まず、私はその後、私は二重の移動なぜscanfからdouble型ではなくfloat型になるのですか?

segment .data 
scanf_fmt: 
     db "%f%ld", 0 

    segment .bss 
    align 16, db 0 
x  resq 1  ; for double fp 
number resq 1  ; for integer 
    align 16, db 0 
res resq 1  ; for double fp 

lea rdi, [fmt] 
lea rsi, [x] 
lea rdx, [number] 
xor eax, eax ; number of fp values(edited from mov rax, 1 ,still looks the same) 
call scanf 

SSE手順について)整列場所に二重のFPをお読みください。

movsd xmm0, [x] 

は、それから私は、デバッグ始まっ:私は読むことをscanfのため1.6で入力。ラベルx

100 movsd xmm0, [x] 
(gdb) p/f x 
$1 = 1.60000002 
(gdb) n 
(gdb) p $xmm0 
$2 = {v4_float = {1.600000002, 0, 0, 0}, v2_double = {5.2..., 0}, ... 

浮動小数点値を移動しますが(私が使用しmovsd、)ではないとして、二重フロート(movss)ここ

を何が起こっているように? scanf(3)から

+2

完全なプログラム、作成方法、実行方法、実行時に入力した内容を表示する必要があります。代わりに、デバッガに表示されると思われるものが必要です。 –

+0

'mov rax、1'はバグです。整数レジスタにポインタを二重に渡し、xmm regsにゼロFP引数を渡します。 –

+0

@RossRidgeビルド: 'yasm -f elf64 -g dwarf2 main.asm; gcc -o main main.o' 実行: '。/ main' 型付き:' 1.6' '{v4_float = {smth、0、0、0}、v2_double = {1.6、0}、..のようなものがあります。 。 –

答えて

3

%fは、必要に応じて署名された浮動小数点数と一致し、次のポインタはfloatへのポインタでなければなりません。

あなたはそれを告げたようなので、scanf関数、[x]float 32ビット単精度を保存。次の32ビットはゼロのままである。

あなたが見た他のすべては、その明白な結果です。


すばやくmanページで「ダブル」を検索することによって見つけることができるようにdoubleの変換指定子は、%lfです。

+0

scanf double浮動小数点数を正確に読み取る方法は?したがって、scanfは、4バイトの単精度浮動小数点だけでなく、IEEE 754に従ってメモリ位置に8バイトの倍精度を配置します。それらのフォーマットは似ていますが、floatの前に4バイトのゼロバイトを埋め込むだけでは、floatから2倍にすることはできません。 –

+2

通常の人のようにmanページで 'double'を検索します。これはCでこれをしていたのと同じです。 –

+0

ああ、明らかに、mans( "double"を読むための "lf")を読む必要があります。今すぐgdbのxmm0が期待どおりに印刷されました。 –

関連する問題