我仍然不了解IMUL在组装中的工作方式

时间:2019-07-05 18:32:24

标签: visual-studio assembly x86 multiplication twos-complement

我是汇编的入门者,我刚刚开始学习它,但我不了解IMUL指令的真正作用

例如,我正在Visual Studio上处理这段代码:


Mat = 0A2A(hexadecimal)

__asm {

    MOV AX, Mat
    AND AL,7Ch
    OR AL,83h
    XOR BL,BL
    SUB BL,2
    IMUL BL
    MOV Ris5,AX
}

Ris5中的结果应为00AA(十六进制),对于前几行,我都很好,从第一行到'SUB BL,2' 结果为AL = AB(AX = 0AAB) 但是从IMUL开始,我陷入了困境。 我知道IMUL通过寄存器或字节或字来执行AL的有符号乘法..并将结果存储在AX中(在这里),但我找不到相同的结果(00AA)

1 个答案:

答案 0 :(得分:3)

MOV AX, Mat    AX = 0x0A2A  (...00101010)
AND AL,7Ch     AX = 0x0A28  (...00101000)
OR AL,83h      AX = 0x0AAB  (...10101011)
XOR BL,BL      BL = 0x00
SUB BL,2       BL = 0xFE
IMUL BL        AX = 0xFFAB * 0xFFFE = 0x00AA
MOV Ris5,AX    Ris5 = 0x00AA

当您不确定两个N位数字时,较低的N位并不关心有符号与无符号,但是在填充数字时,您将进入有符号与无符号乘法指令,就像在某些指令集中看到的那样。为了不失去精度,您希望得到2 * N位数的结果,对学校数学进行分级:

   00000000aaaaaaaa
*  00000000bbbbbbbb
=====================

   AAAAAAAAAAaaaaaa
*  BBBBBBBBBBbbbbbb
====================

签名与未签名,大写字母表示符号扩展名

0xAB = 171无符号= -85有符号

0xFE = 254无符号= -2有符号

无符号乘法171 * 254 = 43434 = 0xA9AA

有符号乘法-85 * -2 = 170 = 0x00AA

低字节与8位操作数相同,并且符号扩展名不起作用:

         bbbbbbbb *a[0]
        bbbbbbbb  *a[1]
       bbbbbbbb   *a[2]
      bbbbbbbb    *a[3]
     bbbbbbbb     *a[4]
    bbbbbbbb      *a[5]
   bbbbbbbb       *a[6]
+ bbbbbbbb        *a[7]
==================
 cyyyyyyyxxxxxxxx       

如果您查找列,则x位不受符号扩展的影响,因此,无符号和有符号的x位相同。 y位会受到影响,而构成结果的第16位的msbit c的进位也会受到影响。

现在该工具不再抱怨这种语法了:

Mat = 0A2A(hexadecimal)

结尾没有h或前面没有0x或$看起来像八进制,但如果八进制(或十进制),则A会导致错误。假设您从0x0A2A开始,我认为您的理解是可靠的。