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/