这是在Mul中使用cbw的正确方法吗?

时间:2019-04-12 06:44:24

标签: assembly x86-16 sign-extension

我从8位和8位寄存器获得乘法。但是,当您拥有16位元之一和8位元之一的功能时,我们如何在进行乘法运算之前进行转换:

问题:需要提供260 * 19的代码片段,并打印结果。我做到了:

mov Ax,260
mov Al,19
cbw;
Mul Ax 
PutInt Ax

1 个答案:

答案 0 :(得分:1)

mov Ax,260
mov Al,19

AL寄存器是AX寄存器的下半部分。

            AX
    /-----------------\
MSB xxxx xxxx xxxx xxxx LSB
    \-------/ \-------/
        AH        AL

第二条指令mov al, 19因此会错误地覆盖您的第一个数字。

Mul Ax 

字节大小的mul指令将AL寄存器乘以指定的字节大小的操作数。
字长的mul指令将AX寄存器乘以指定的字长操作数。

使用mul ax将计算出AX * AX,这不是您想要的。您想将不同的数字相乘。

AX与另一个BX之类的寄存器一起使用可以解决这两个问题。


cbw的处理方式取决于我们如何看待代码。

  • 如果您将数字用作立即数(260,19),那么即使对于小数字19也只需使用字大小的寄存器:

    mov     bx, 260
    mov     ax, 19
    mul     bx       ; Product AX * BX is in DX:AX but here DX=0
    PutInt  ax
    

    甚至让汇编器做乘法:

    mov     ax, 260 * 19
    PutInt  ax
    
  • 如果数字来自内存(大小不同的变量),则需要扩展较小的数字。

    • 无符号数字,请使用mul进行无符号乘法

      mov     bx, wNum  ; [0,65535]
      mov     al, bNum  ; [0,255]
      mov     ah, 0
      mul     bx        ; Product AX * BX is in DX:AX
      PutInt  ax
      

      在这种情况下,我建议不要使用cbw!使用cbw会使所有128以上的数字都皱缩。

    • 带符号的数字,使用imul进行带符号的乘法

      mov     bx, wNum  ; [-32768,32767]
      mov     al, bNum  ; [-128,127]
      cbw
      imul    bx        ; Product AX * BX is in DX:AX
      PutInt  ax
      

      cbw是从AL扩展有符号字节的正确选择。