两个负数相乘时 imul 的 MASM32 问题

MASM32 problems with imul when multiply two negative numbers

我开始注册数字-100,现在在al中以十六进制形式存储9C,与我对寄存器bl所做的相同,所以在bl中也存储了9C。 这就是问题所在,当我这样做时:

imul ebx

我在寄存器 eax 中得到 00005F10h,它是十进制的 24336,而不是我预期得到的 10000。 我究竟做错了什么? 这是我执行此乘法的代码部分:

mov eax, 0
mov ebx, 0
mov ecx, 0
mov al, [sbAval+esi]
mov bl, [sbAval+esi]

power:
imul ebx
cmp ecx, 2
je powerDone
inc ecx
jmp power

sbAval 是 SBYTE 数据类型

这里我在eax和ebx中存储了9C registers before imul

这里是 imul 之后的寄存器 registers after imul

-100 在 32 位中不是 0x9c,而是 0xffffff9c。如果您将 0x9c 放入寄存器(而不是实际的整数 -100),那么您将得到 156。您可能不会对 156*156=24336 感到惊讶。这可能会造成混淆。

根据您的编辑,您似乎无法使用 SBYTE 自然地执行此操作,因为指令的性质是用 0 填充较短的数据类型(并将其视为正数)。使用 movsx 在将 SBYTE 移动到寄存器时保留符号。

假设二进制补码系统,0x9C 以单个字节存储时为负,以两个或多个字节存储时为正。

这是因为在二进制补码系统中,最高有效位(即最左边的一位)表示符号,1 使其为负数。

当您将 space 扩展到 MSB 为 0 的 32 位时 - 该数字被“处理”为正数。

一种可能的解决方案是将 100 存储在 ALBL 中(在清除 EAXEBX 之后,就像您在代码中所做的那样) ,然后否定 EAXBAX。例如。 NEG EAX ( How to convert a positive number to negative in assembly )