2016-10-28 7 views
1

Angenommen, ich möchte eine große Zahl mit einer anderen (vielleicht kleinen) Zahl in der Baugruppe multiplizieren. Die große Zahl (Multiplikand) wird in DX:AX gespeichert und der Multiplikator wird in BX gespeichert. Die Anweisung MUL funktioniert nur unter AX. Also was mit DX zu tun?Assembly multiplication

Zum Beispiel ist die Zahl 0001:0000H (65536) und ich mag es multiplizieren 2.

number  dw 0000h, 0001h 
... 
mov ax, [number] 
mov dx, [number+2] 
mov bx, 2 
mul bx ; it is ax*2 or 0000*2 

Daher ist das Ergebnis Null! Irgendeine Idee dazu?

+1

'axe' enthält die Adresse von' 0000', nicht value. Wahrscheinlich wollten Sie 'mov ax, [number]' und 'mov dx, [number + 2]' (+2, weil 'dw' 2 Bytes lang ist). – Ped7g

+0

Bewegen Sie Ihre Nummer von DX: AX in EAX :) –

+0

Ja, auch ist das nur 16bit x86? Und möchten Sie signierte oder vorzeichenlose Nummern? ('mul' vs' imul') – Ped7g

Antwort

4

Lassen Sie uns so tun, dies ist 286, so dass Sie nicht eax haben.

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 

Es ist die gleiche Art und Weise wie, wenn Sie Zahlen auf dem Papier multiplizieren, nur bewegen Sie nicht von * 10 Komponenten, sondern ausbeuten der Größe der Natur 16b registrieren, indem Sie * 65536 (0x10000) Komponenten zu bewegen, um es zu machen in weniger Schritte.

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

Wenn man diesen 48b-Wert als drei Wörter im Speicher hat, wird es höchst unpraktisch, wenn man ein weiteres Wort mit Nullwert hinzufügt, um wenigstens einen gültigen 64-Bit-Wert zu erhalten, wäre es wahrscheinlich besser, dann kommt es darauf an, was man damit machen will Wert sowieso. – Ped7g