C 在程序集中添加浮点数/双精度数字

C 在程序集中添加浮点数/双精度数字,c,assembly,x86,x87,C,Assembly,X86,X87,我正在尝试内联汇编,我正在尝试在内联汇编中添加十进制数(不,不是整数)。问题是,当我调用以下函数时: inline double ADD(double num1, double num2) { double res; _asm{ push eax; push the former state of eax onto stack mov eax, num1; add eax, num2; mov res, eax; pop eax; restore t

我正在尝试内联汇编,我正在尝试在内联汇编中添加十进制数(不,不是整数)。问题是,当我调用以下函数时:

inline double ADD(double num1, double num2) {
  double res;
_asm{

    push eax; push the former state of eax onto stack
    mov eax, num1;
    add eax, num2;
    mov res, eax;
    pop eax; restore the former state of eax now that we are done   
     }  return res;}
编译器抱怨内联程序集(除push和pop指令行之外的所有程序集行)的操作数大小不正确。所以我必须改为整数类型,比如unsigned long,然后它就可以工作了,但当然只支持整数类型;小数结果四舍五入


是否有任何方法可以添加允许8.4等十进制结果的汇编程序?

我已经十年没有完成x87汇编了,但它应该是这样的:

fld num1   ; load num1 and push it onto the fpu stack
fld num2   ; load num2 and push it onto the fpu stack
faddp      ; pop two numbers, add them, push sum on the stack
fstp res   ; pop sum from the stack and store it in res

您需要一组不同的指令来操作浮点数。这里有一个介绍应该会有所帮助:

您可能想要的指令是ADDSD,但我不确定

以下是英特尔指令集手册的链接。


他们过去常常免费邮寄硬拷贝给你,但现在看来已经不是这样了。

上面的答案是,你必须将操作数推到FP堆栈上,然后弹出结果,这是正确的

但是,“操作数大小不正确”错误的直接原因是“扩展”寄存器、“e_ux”(例如eax)是32位的,而双精度浮点数是64位的。

尝试以下方法:

_asm{

movq xmm0,[num1]
addpd xmm0, [num2];
movq [res],xmm0
// sse2
 }

注意:二进制浮点数(
float
double
等)不是十进制浮点数,也不是实数(在数学意义上)。1.8和9.8都不能精确表示为double。你应该关注的原因有很多,其中一个是@fredflow(关于其他方面有大量的资源,但它们解释得很深入,因此需要大量的数学和/或有点虚幻的知识才能很好地理解,所以让我们先别说了)。遗憾的是,它在大多数情况下都是有效的,但你会遇到“奇怪的错误”在这样的计算中,我想我要警告你。只要搜索一下,就可以看到上百个例子——这是最常见的问题之一。请不要
推eax
。这是唯一一个你不需要保存的寄存器,因为它会返回结果。仅供参考,eax是32位宽,但双倍是64位。这永远不会起作用。这些说明是什么ns的意思是?我只知道基本的汇编指令。为了方便起见,我添加了注释。您可能应该仔细阅读x87,它是一个堆栈机器(与x86相反,x86是一个寄存器机器)。谢谢你的评论。这很有帮助,但它抱怨faddp被赋予了非法的操作数。我将其更改为fadd,它成功了!我现在可以使用浮点数了!!!!!耶!非常感谢!Dfadd将导致堆栈不平衡,请尝试以下变体:
faddp st1,st0
faddp st1,st
faddp st(1),st(0)
我做了最后一个你显示的代替fadd的,它显示了与fadd完全相同的结果,所以这很好,加上它不会像fadd那样明显地损害堆栈:)。谢谢你,珍。另外,我看到了它们是如何工作的,其中st(num)引用堆栈的某些区域。对我来说,良好的学习经验:)。+1推荐SSE2而不是老式的x87指令。