こんにちは、アセンブリを学び、x86_64 で浮動小数点数を扱う方法を学ぼうとしています。私が理解していることから、引数は xmm0、xmm1、xmm2 などで渡され、結果は xmm0 で返されます。だから私は一緒に倍増する単純なアセンブリ関数を作ろうとしています。ここに関数があります
.text
.global floatadd
.type floatadd,@function
floatadd:
addsd %xmm1,%xmm0
ret
そして、これも私が使用しているCコードです。
#include<stdio.h>
int main(){
double a = 1.5;
double b = 1.2;
double c = floatadd(a,b);
printf("result = %f\n",c);
}
私はgdbで何が起こっているかを追跡しようとしています。関数にブレークポイントを設定すると、xmm0 が 1.5、xmm1 が 1.2 であり、それらを合計すると 2.7 であることがわかります。gdb print $xmm0 で v2_double = {2.7000000000000002, 0} が得られます ただし、関数がメインから戻って呼び出すと
cvtsi2sd %eax,%xmm0
Print $xmm0 は v2_double = {2, 0} になります。gcc がそれを呼び出す理由、または 64 ビット レジスタの代わりに 32 ビット レジスタを使用する理由がわかりません。修飾子 %lf と %f を使用してみましたが、どちらも同じことを行います。
何が起こっている?