【问题标题】:How to get the value of the product after multiplying the values of two registers?两个寄存器的值相乘后如何得到乘积的值?
【发布时间】:2019-04-05 05:37:05
【问题描述】:

假设寄存器 ax = 50 和 cx = 1000

做完之后

mul cx

十六进制乘积将被分成两半,格式为 (dx ax) 我怎样才能获得产品的全部价值? (在这种情况下为 50,000)

【问题讨论】:

  • DX:AX DX 中的 32 位结果是高 16 位,AX 是低 16 位。由于 50,000 的结果只能放入 16 位寄存器,因此 DX 将为零,而 AX 将有 50,000。
  • 1000 和 50 是十六进制还是十进制?我上面的评论假设十进制。那么是 0x1000*0x50 还是 1000*50
  • 你是对的,它是小数
  • 这是一个更棘手的问题,具体取决于操作。你打算支持多大的数字?我现在看到这说 irvine32。如果您正在执行 32 位代码,那么您可以 mul EAX 和 ECX(在 EDX:EAX 中结合支持 64 位结果的 32 位寄存器)
  • 或者您可以只使用imul eax, ecx 并获得不带高位的 32 位结果(这样会更快)

标签: assembly x86 computer-science masm irvine32


【解决方案1】:

鉴于您使用的是 irvine32,您可以编写 32 位代码。
在 2018 年编程 16 位真的没有意义了。 32 位代码于 1985 年推出,您现在应该继续前进。

话虽如此。

mov ax,[a]       //part a
mov cx,[b]       //part b
mul cx         //ax:dx = a * b
cmp dx,0       //if dx=0 then ax contains the whole result
jne overflow   //handle overflow
//process ax

如果你加入了理智的人的世界,你就可以做到

movzx eax, word ptr [a]
movzx ecx, word ptr [b]
imul eax,ecx              //eax=eax*ecx
//test to see if it fits into a word
cmp eax,0xFFFF
ja,overflow               //result does not fit into a word.
//or, test to see if it fits into a (signed) int
js,overflow

如果您要将结果存储在unsigned int 中,则无需对其进行测试。

因为您的输入是 16 位正数,所以输出永远不会溢出 32 位无符号目标。 imul 的另一个好处是 如果 您使用双操作数版本,它不会破坏 edx 寄存器。

见:IMUL

'我怎样才能得到整个价值[...]? (50,000 [...]'
ax 是一个 16 位寄存器,如果您将它用作无符号字,那么它可以保存从 0 到 65535 的值。因为计算的目标是dx:ax,所以符号位进入dx
但是,mul 是一个无符号乘法,因此您不应该输入负值。
如果您想要有符号乘法,请使用imul
您也可以使用imul 进行无符号乘法,只要您可以确保两个输入的最高有效位为零。 (这就是movzx 所做的)。

【讨论】:

  • 如果你不改变ab的大小,你不能只改变mov eax, a,如果它仍然是word。你可能想要movzx eax, word ptr [a] / movzx eax, word ptr [b] / imul eax, ecx。如果您不打算使用高半部分,那么使用传统的单操作数 mul 也没有任何意义;它更慢并且破坏了 EDX。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-17
  • 2018-04-12
  • 2016-01-18
  • 1970-01-01
  • 1970-01-01
  • 2018-10-02
  • 2017-10-29
相关资源
最近更新 更多