2016-10-28 3 views
1

アセンブリで大きな数値を別の(おそらく小さい)数値で乗算したいとします。大きい数字(被乗数)は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 

を掛けたいです!それについてのアイデア?

+1

'ax'には値ではなく '0000'のアドレスが含まれています。おそらく、 'mov ax、[number]'と 'mov dx、[number + 2]'( 'dw'は2バイトであるため+2)をしたかったでしょう。 – Ped7g

+0

DX:AXからEAXに番号を移動してください:) –

+0

ええ、これも16bit x86だけですか?あなたは署名付きの番号や無署名の番号をお探しですか? ( 'mul'と' imul') – Ped7g

答えて

4

これは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個のコンポーネントによって移動するが、それで作る* 65536(0x10000番地)コンポーネントによって移動するサイズの自然を登録16bが活用していないのと同じ方法ですより少ないステップ。

I.e.

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

その48bの値を3つの単語としてメモリに入れることは、おそらく非常に実用的ではなく、0の値を持つ単語を1つ増やして、少なくとも64bの値を有効にすることが望ましいでしょう。とにかく価値。 – Ped7g