8086汇编编程简单算法

时间:2012-11-19 10:11:16

标签: assembly x86-16

我如何将汇编中的两个32位数字或另一个32位数字再乘以16位,谁知道算法呢?

data1 dw 32bit
data2 dw 32bit    
mov ax,data2
Mul data1

2 个答案:

答案 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]