C版功能:
float foo1 (float a, float b)
{
return sin(a) + b;
}
double sin(double x);
double cos(double x);
cos
用于以后的功能。
我们的任务是将foo1
转换为汇编,但正如您所见,a
是float
而sin
需要double
参数。几个星期以来一直在将C翻译成汇编代码,但老实说,此处不知道该怎么做。
答案 0 :(得分:3)
gcc是你的朋友 - 用gcc -S
进行编译表明你可能希望使用cvtss2sd
进行浮点数转换,将cvtsd2ss
用于将双结果转换回浮点数:
_foo1:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movss 8(%ebp), %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, (%esp)
calll _sin
fstpl -16(%ebp)
movss 12(%ebp), %xmm0
cvtss2sd %xmm0, %xmm0
addsd -16(%ebp), %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -4(%ebp)
flds -4(%ebp)
addl $24, %esp
popl %ebp
ret
编辑:这似乎是某种带有任意约束的家庭作业。如果您需要避免SSE指令,那么只需将-mno-sse
添加到命令行(gcc -mno-sse ...
)即可获得:
_foo1:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
flds 8(%ebp)
fstpl (%esp)
calll _sin
fadds 12(%ebp)
fstps -4(%ebp)
flds -4(%ebp)
addl $24, %esp
popl %ebp
ret
编辑2 :对于更紧凑的代码,您可以省略堆栈帧(gcc -fomit-frame-pointer ...
) - 但请注意,在调试或分析时,您将失去一些功能:
_foo1:
subl $12, %esp
flds 16(%esp)
fstpl (%esp)
calll _sin
fadds 20(%esp)
fstps 8(%esp)
flds 8(%esp)
addl $12, %esp
ret