Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 16位x 32位=>48位的汇编乘法_Assembly_X86 16_Bigint_Extended Precision - Fatal编程技术网

Assembly 16位x 32位=>48位的汇编乘法

Assembly 16位x 32位=>48位的汇编乘法,assembly,x86-16,bigint,extended-precision,Assembly,X86 16,Bigint,Extended Precision,假设我想用一个大的数字乘以汇编中的另一个小的数字。大数字乘法器保存在DX:AX中,乘法器保存在BX中。MUL指令仅在AX上运行。那么如何处理DX呢 例如,数字是0001:0000h65536,我想把它乘以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

假设我想用一个大的数字乘以汇编中的另一个小的数字。大数字乘法器保存在DX:AX中,乘法器保存在BX中。MUL指令仅在AX上运行。那么如何处理DX呢

例如,数字是0001:0000h65536,我想把它乘以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

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


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

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


ax包含0000的地址,而不是值。你可能想做mov-ax,[number]和mov-dx,[number+2]+2,因为dw是2字节。把数字从dx:ax移到EAX:yeah,这也是16位x86吗?你想要有符号的还是无符号的数字?mul vs IMULLOAD dx寄存器无效。16位乘法仅使用dx作为输出寄存器:高阶位。这里,dx:ax中的结果都是零。在16位8086汇编中,不能用一条指令乘以32位数字。这就是它成为16位指令集的原因。您需要多个16位乘法和一些移位和加法:a+b*2^16*c+d*2^16=ac+bc+ad*2^16+bd*2^32。您可以跳过最后一项,因为它的值大于32位。ax包含0000地址,而不是值。你可能想做mov-ax,[number]和mov-dx,[number+2]+2,因为dw是2字节。把数字从dx:ax移到EAX:yeah,这也是16位x86吗?你想要有符号的还是无符号的数字?mul vs IMULLOAD dx寄存器无效。16位乘法仅使用dx作为输出寄存器:高阶位。这里,dx:ax中的结果都是零。在16位8086汇编中,不能用一条指令乘以32位数字。这就是它成为16位指令集的原因。您需要多个16位乘法和一些移位和加法:a+b*2^16*c+d*2^16=ac+bc+ad*2^16+bd*2^32。您可能会跳过最后一项,因为它的值大于32位。将48b值作为三个字存储在内存中可能会变得非常不切实际,再添加一个零值字,使其至少有效64b值可能会更好,同样,这取决于你想用那个值做什么。把48b值作为三个字放在内存中可能会变得非常不切实际,再加一个零值的字使它至少有效64b值可能会更好,然后这取决于你想用那个值做什么。
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
  13
* 37
----
  91 (13 * 7)
 39_ (13 * 3, shifted left by *base (=10))
---- (summing the intermediate results, the 39 "shifted")
 481 (13 * 37)