assembly:如何将一个float扩展为一个double函数用于sin函数

时间:2014-06-17 09:36:02

标签: c assembly floating-point x86 att

C版功能:

float foo1 (float a, float b) 
{
    return sin(a) + b;
}

double sin(double x);
double cos(double x);

cos用于以后的功能。 我们的任务是将foo1转换为汇编,但正如您所见,afloatsin需要double参数。几个星期以来一直在将C翻译成汇编代码,但老实说,此处不知道该怎么做。

1 个答案:

答案 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