【问题标题】:Assembly multiplication of 16-bit x 32-bit => 48-bit16 位 x 32 位的汇编乘法 => 48 位
【发布时间】:2017-03-11 16:13:24
【问题描述】:

假设我想在汇编中将一个大数乘以另一个(也许很小)数。大数(被乘数)保存在DX:AX,乘数保存在BXMUL 指令仅在 AX 上运行。那么DX怎么办呢?

例如,数字是0001:0000H(65536),我想把它乘以2。

number     dw   0000h, 0001h
...
mov    ax, [number]
mov    dx, [number+2]
mov    bx, 2
mul    bx   ; it is ax*2 or 0000*2

因此结果为零!有什么想法吗?

【问题讨论】:

  • ax 包含0000 的地址,而不是值。你可能想做mov ax,[number]mov dx,[number+2](+2,因为dw是2个字节)。
  • 把你的号码从 DX:AX 移到 EAX :)
  • 是的,这也只是 16bit x86 吗?你想要有符号还是无符号的数字? (mulimul
  • 加载dx寄存器没有效果。 16 位乘法只使用 dx 作为输出寄存器:高位。这里 dx:ax 中的结果全为零。
  • 您不能将 16 位 8086 汇编中的 32 位数字与一条指令相乘。这就是使它成为 16 位指令集的原因。您需要不止一个 16 位乘法和一些移位和加法: (a+b*2^16) * (c + d*2^16) = ac + (bc + a d)*2^16 + (bd*2^32)。您可能会跳过最后一项,因为它的值大于 32 位。

标签: assembly x86-16 bigint extended-precision


【解决方案1】:

假设这是 286,所以你没有 eax

number dd 0x12345678      ; = dw 0x5678, 0x1234
result dw 0, 0, 0         ; 32b * 16b = 48b needed
    ...
    mov    ax,[number]    ; 0x5678
    mov    cx,[number+2]  ; 0x1234 ; cx, dx will be used later
    mov    bx,0x9ABC
    ; now you want unsigned 0x12345678 * 0x9ABC (= 0xB00DA73B020)
    mul    bx             ; dx:ax = 0x5678 * 0x9ABC
    ; ^ check instruction reference guide why "dx:ax"!
    xchg   cx,ax
    mov    di,dx          ; di:cx = intermediate result
    mul    bx             ; dx:ax = 0x1234 * 0x9ABC
    ; put the intermediate multiplication results together
    ; into one 48b number dx:di:cx
    add    di,ax
    adc    dx,0
    ; notice how I added the new result as *65536 to old result
    ; by using different 16bit registers

    ; store the result
    mov    [result],cx
    mov    [result+2],di
    mov    [result+4],dx

这与你在纸上乘数的方式相同,只是你不移动 *10 个分量,而是利用 16b 寄存器大小的性质移动 *65536 (0x10000) 个分量以减少步骤。

  13
* 37
----
  91 (13 * 7)
 39_ (13 * 3, shifted left by *base (=10))
---- (summing the intermediate results, the 39 "shifted")
 481 (13 * 37)

【讨论】:

  • 在内存中将 48b 值作为三个单词可能会变得非常不切实际,添加一个零值的单词以使其至少有效的 64b 值可能会更好,然后再次取决于无论如何你想用这个值做什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-16
  • 1970-01-01
  • 2014-01-09
  • 1970-01-01
  • 2010-11-08
相关资源
最近更新 更多