16 位 x 32 位的汇编乘法 => 48 位
Assembly multiplication of 16-bit x 32-bit => 48-bit
假设我想在汇编中将一个大数乘以另一个(可能是小的)数。大数(被乘数)保存在DX:AX
中,乘数保存在BX
中。 MUL
指令仅在 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
因此结果为零!有什么想法吗?
假设这是 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)
假设我想在汇编中将一个大数乘以另一个(可能是小的)数。大数(被乘数)保存在DX:AX
中,乘数保存在BX
中。 MUL
指令仅在 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
因此结果为零!有什么想法吗?
假设这是 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)