如何在 x86 程序集中移动两个浮点数的 mul 的结果?
Posted
技术标签:
【中文标题】如何在 x86 程序集中移动两个浮点数的 mul 的结果?【英文标题】:How do I move the result of a mul of two floats in x86 assembly? 【发布时间】:2014-06-23 16:31:39 【问题描述】:我目前正在尝试将两个浮点数相乘,一个来自浮点向量(存储在 ebx 中的地址)和我存储在 ecx 中的值。
我已经确认输入值是正确的,但是,例如,如果我将 32 和 1 相乘,EAX 中的值将变为 00000000,而 EDX 中的值将变为 105F0000。根据我对 MUL 的理解,这是因为它将结果的高位存储在 EDX 中,而将低位存储在 EDX 中。问题是,如何将结果移动到输出变量 (returnValue) 中?这是有问题的代码sn-p:
AddColumnsIteration:
cmp esi, 4 // If we finished storing the data
jge NextColumn // Move to the next column
mov eax, [ebx][esi * SIZEOF_INT] // Get the current column
mul ecx // Multiply it by tx
add [returnValue][esi * SIZEOF_INT], eax // Add the data pointed at by eax to the running total
inc esi // Element x, y, z, or w of a Vec4
jmp AddColumnsIteration // Go back to check our loop condition
我知道如果我使用 x87 命令或 SSE 指令,这将容易几个数量级,但问题的约束需要纯 x86 汇编代码。对不起,如果这看起来有点基本,但我仍在学习组装的特质。
提前感谢您的帮助,祝您有愉快的一天
【问题讨论】:
我不知道是什么导致了负面评价 首先检查您的代码是否有效! mul 似乎缺少一个操作数。而且您正在尝试使用整数算术而不对浮点值进行任何解码和编码(错误)。对于输出,您的 C++ 环境需要它吗?你可能也有一个输出地址,或者如果操作是“*=”,那么用重新缩放的向量覆盖旧向量。 MUL 不是一个操作数,它采用你给它的任何值并将存储在 EAX 中的值乘以它。浮点值的编码或解码是什么意思(正如我所说,我是汇编新手)?结果被输出到 Vec4 中,它只是一个具有 4 个浮点数的结构,全部初始化为零。所以基本上,代码将 4x4 矩阵乘以 4x1 向量并将其存储在 Vec4 输出中。 输出的 Vec4 是一个局部变量。 好吧 mul 只有一个操作数,所以你就在那里。但是 mul 是一个整数指令。如果您在 EAX 和 ECX 中传递浮点值,它们将被视为整数。所以乘积是表示不一样的浮点数的整数的乘积。 32 编码为浮点数是 0x42000000 而不是 0x20,1 编码为 0x3f800000。乘法得到 0x105f000000000000 而不是 32!您必须使用 fmul 或发明自己的 fmul 才能正确使用。 【参考方案1】:您将浮点数表示为整数,而不是浮点数本身:
1.0 = 0x3f800000
32.0 = 0x42000000
0x3f800000 * 0x42000000 = 0x105f000000000000
要真正进行浮点运算,您需要执行以下操作之一:
使用 x87。 使用 SSE。 编写您自己的软件乘法,将编码分离为符号位、指数和有效位,对符号位进行异或运算以获得乘积的符号位,将指数相加并调整偏差以获得乘积的指数,将乘积相乘有效位和四舍五入得到产品的有效位,然后将它们组合起来产生结果。显然,前两个选项要简单得多,但听起来由于某种原因它们不是一个选项(尽管我真的无法想象为什么不这样做;x87 和 SSE 是 “纯 x86 汇编代码”,因为它们已经成为 ISA 的一部分很长时间了)。
【讨论】:
我没有把它写成答案,因为问题是关于如何返回向量,但无论如何都值得一票,因为发布的是错误的。 x87 在 486DX 下工作,所以对于 x87,是的,它是纯 x86 程序集。 是的;不幸的是,在提问者成功计算要存储的结果之前,甚至讨论如何存储结果都没有意义。以上是关于如何在 x86 程序集中移动两个浮点数的 mul 的结果?的主要内容,如果未能解决你的问题,请参考以下文章