我如何将汇编中的两个32位数字或另一个32位数字再乘以16位,谁知道算法呢?
data1 dw 32bit
data2 dw 32bit
mov ax,data2
Mul data1
答案 0 :(得分:2)
首先,dw
用于创建16位(“单词”)值。它不会保持32位值。您需要使用dd
来存储32位“双字”,或使用一对16位值。
要将一对32位值相乘,结果可以是64位(例如0xFFFFFFFF * 0xFFFFFFFF = 0xFFFFFFFE00000001)。对于8086(而不仅仅是80386或更高版本的实模式代码),存在MUL指令,但它仅限于乘以2个16位值(并获得32位结果)。这意味着您希望将每个32位值视为一对16位值。
如果A被分成A_low(第一个32位数的最低16位)和A_high(第一个32位数的最高16位),并且B被分成B_low和B_high。同样的方式;然后:
A * B = A_low * B_low
+ ( A_high * B_low ) << 16
+ ( A_low * B_high ) << 16
+ ( A_high * B_high ) << 32
代码可能如下所示(NASM语法):
section .data
first: dw 0x5678, 0x1234 ;0x12345678
second: dw 0xDEF0, 0x9ABC ;0x9ABCDEF0
result: dw 0, 0, 0, 0 ;0x0000000000000000
section .text
mov ax,[first] ;ax = A_low
mul word [second] ;dx:ax = A_low * B_low
mov [result],ax
mov [result+2],dx ;Result = A_low * B_low
mov ax,[first+2] ;ax = A_high
mul word [second] ;dx:ax = A_high * B_low
add [result+2],ax
adc [result+4],dx ;Result = A_low * B_low
+ (A_high * B_low) << 16
mov ax,[first] ;ax = A_low
mul word [second+2] ;dx:ax = A_low * B_high
add [result+2],ax
adc [result+4],dx ;Result = A_low * B_low
+ A_high * B_low
+ (A_low * B_high) << 16
mov ax,[first+2] ;ax = A_high
mul word [second+2] ;dx:ax = A_high * B_high
add [result+4],ax
adc [result+6],dx ;Result = A_high * B_high
+ A_high * B_low
+ (A_low * B_high) << 16
+ (A_high * B_high) << 32
如果您实际使用的是80386或更高版本,那么它就简单得多了:
section .data
first: dd 0x12345678
second: dd 0x9ABCDEF0
result: dd 0, 0 ;0x0000000000000000
section .text
mov eax,[first] ;eax = A
mul dword [second] ;edx:eax = A * B
mov [result],eax
mov [result+4],edx ;Result = A_low * B_low
答案 1 :(得分:0)
它无法正常工作。如果你有一个随身携带怎么办:
adc [result+4],dx ;Result = A_low * B_low + (A_high * B_low) << 16 ???
您将在[result+6]
丢失一个随身物品。您必须在adc [result+6],0
[result+4]