将有符号数与无符号数相乘时,应该使用“mul”还是“imul”?

7 x86 assembly unsigned signed multiplication

我发现 和 都mul可以imul用来将有符号数乘以无符号数。

例如:

global _start

section .data
    byteVariable DB -5

section .text
_start:

mov al, 2
imul BYTE [byteVariable]
Run Code Online (Sandbox Code Playgroud)

可以用 替换imulmul结果还是一样(-10)。

有符号数与无符号mul数相乘时和imul完全相同,还是有区别?

har*_*old 4

正如评论中提到的,上半部分是不同的。如果您不关心上半部分,则可以在所有形式中使用 或mul, imul(单操作数形式生成上半部分,但在这种情况下您将忽略它)。

\n\n

如果您确实关心上半部分,则它们本身都不起作用,因为它们只是将 unsigned*unsigned 和signed*signed 相乘,但您可以相当容易地修复它mulimul

\n\n

考虑有符号字节的位权重为 -128, 64, 32, 16, 8, 4, 2, 1,而无符号字节的位权重为+ \xe2\x80\x8b128, 64, 32, 16, 8 , 4, 2, 1。因此,您可以将带x符号格式的无符号值表示为(我知道这很令人困惑,但这是我能做的最好的)x + 256 x_7(其中 的x_7位 7 是x)。最简单的查看方法可能是将其拆分:x + 2 * 128 * x_7。这里发生的是补偿 -128 权重,首先通过添加位 7 128 次的值来删除它,然后通过再次执行一直到 +128 权重,当然这可以在一步。

\n\n

无论如何,将其乘以某个有符号数y并计算出来256 x_7 y + xy,其中xy是 的(双角)结果imul256 x_7 y意味着“y如果设置了 的符号,则添加到上半部分x”,因此可能的实现是(未测试)

\n\n
; al has some unsigned value\nmov dl, al\nsar dl, 7\nand dl, [signedByte]\nimul BYTE [signedByte]\nadd ah, dl\n
Run Code Online (Sandbox Code Playgroud)\n\n

当然,您可以对一个操作数进行符号扩展,对另一个操作数进行零扩展,并使用 16 位乘法(任意,因为上半部分与这种方式无关)。

\n