c - 汇编:如何将 float 扩展为 double 以便使用 sin 函数

标签 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 转换为汇编,但正如您所看到的,a 是一个 float 并且 sin 需要一个 参数。几周来我们一直在将 C 语言转换为汇编代码,但说实话,我不知道在这一点上该怎么做。

最佳答案

gcc 是你的 friend - 使用 gcc -S 编译建议你可能需要使用 cvtss2sd 进行浮点到 double 转换,使用 cvtsd2ss 进行浮点到 double 转换将 double 结果转换回 float :

_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

关于c - 汇编:如何将 float 扩展为 double 以便使用 sin 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24260362/

相关文章:

floating-point - 散列浮点向量的好方法?

python - 在 Python 中比较数字的一般方法

python - 将 float 分配为字典键会改变其精度 (Python)

assembly - MIPS - MIPS 如何为堆栈中的数组分配内存?

c - 为什么将 char 传递给函数会改变它在 c 中的值?

java - 将 java 变量数据映射到 C 结构并编写一个 c 兼容文件

计算字符串数组中的字符数?

assembly - 在 8086 实模式下绘制图形时避免闪烁/闪烁

c - 尝试缓冲 malloc() 分配的溢出值

c - 在服务器代码中收到来自 8080 的请求后,为客户端分配一个新的套接字