2016-09-21 6 views
0

ich ziemlich neu bin in Versammlung, und ich habe einen hardtime mit negativer Zahl zu tunMultiplikation in der Montage mit einem negativen Zahl und führen

#include <stdio.h> 
void main() { 
    short int mat1[] = {-1,-2, 4,5, 4,-2}; // first array 
    short int mat2[] = {2,0,0,0, 0,2,0,0}; // second array 
    int mat3[1024]; // result array 

    __asm { 
     MOV AX, mat1[0] ; mat1[0]:= -1 
     MOV BX, mat2[0] ; mat2[0]:= 2 
     ; my problem is how i can do this 
     ; mat3[0] = mat1[0] * mat2[0] ; 
     ; (operation result -> mat3[0] = -2) 
    } 
} 

P. S. Dies ist für meine Hausaufgaben Dank im Voraus


Neue Frage:

Nach einigem Montagevorgang versuchen:

MOV AX, mat1[ECX] ; eax is 0 and mat1[ecx] is -1 

aber nach dieser Operation wie AX kommen wird auf 65.535 und nicht bis 1? Wie kann ich richtige Multiplikation dann tun, wenn AX-Register nicht korrekt ist? Ich bin ganz durcheinander bringen, wie Komplement 2.


ich eine andere Frage kam zu behandeln. derzeit habe ich diesen Code, wo ich IMUL Ergebnis zu Array verschieben.

MOV WORD PTR mat3[ECX*4]+0, AX 
    MOV WORD PTR mat3[ECX*4]+2, DX 

Meine Frage ist, wie kann ich das IMUL-Ergebnis zum aktuellen Array [idx] -Wert hinzufügen?

mit diesem wo mat3 [aktueller Index] = 0, ist die Operation korrekt. aber wenn zum Beispiel mat3 [aktueller Index] = -2, habe ich eine andere Zahl als das, was ich erwarte.

ADD WORD PTR mat3[ECX*4]+0, AX 
    ADD WORD PTR mat3[ECX*4]+2, DX 

Ich danke Ihnen im Voraus für Ihre Hilfe

+0

Keine Notwendigkeit zu beantworten. Ich habe es schon herausgefunden. – whebz

+0

Siehe auch [meine Antwort hier zum Multiplizieren von 16-Bit-Zahlen und Erzeugen eines 32-Bit- ("int") Ergebnisses (http://stackoverflow.com/questions/39581293/invalid-instruction-operands-on-mov-ah) -word-Variable-und-Using-imul-on-16-bi/39582213 # 39582213). –

Antwort

3

Mit der 8086-Architektur gibt es zwei Befehle zwei Zahlen zu multiplizieren, aber verschiedene Argumente verwendet werden können:

Val8 DB 12  ; 8-bit variable 
Val16 DW 12345 ; 16-bt variable 

MUL BL   ; Unsigned multiply of 8-bit register 
MUL [Val8]  ; Unsigned multiply of 8-bit memory location 
MUL BX   ; Unsigned multiply of 16-bit register 
MUL [Val16] ; Unsigned multiply of 16-bit memory location 

IMUL BL   ; Signed multiply of 8-bit register 
IMUL [Val8]  ; Signed multiply of 8-bit memory location 
IMUL BX   ; Signed multiply of 16-bit register 
IMUL [Val16] ; Signed multiply of 16-bit memory location 

Aber .. Wenn es zwei Variablen multipliziert, wo ist die zweite Variable? Die Antwort lautet, dass die zweite Variable immerAL für 8-Bit-Multiplikationen und immerAX für 16-Bit-Multiplikationen ist.

  • Das Ergebnis einer 8-Bit-Multiplikations kann bis zu 16 Bits, so dass es ist immer in AX gespeichert.
  • Das Ergebnis einer 16-Bit-Multiplikation kann bis zu 32 Bit betragen! Oh oh! Der 8086 hat keine 32-Bit-Register! Wo speichert es das Ergebnis? In DX:AX. Das heißt, es speichert die hohen 16 Bits in DX und die niedrigen 16 Bits in AX.

für Ihren Code, statt mat2[0] in BX bewegen, können Sie einfach IMUL es direkt aus dem Speicher - und ja, sollten Sie IMUL verwenden, da Sie eine mehrfach unterzeichnet werden soll. Wenn Sie das Ergebnis IMUL haben, müssen Sie das Ergebnis unter mat3[0] speichern.Da Sie DX:AX mit einer Anweisung nicht verschieben können, benötigen Sie zwei. Ich weiß nicht, welche Assembler Sie verwenden, aber in der Regel die Syntax wäre so etwas wie dieses:

MOV WORD PTR mat3[0]+0, AX 
MOV WORD PTR mat3[0]+2, DX 

Blick auf die oben sorgfältig! mat3[0] ist ein 32-Bit-Int, so dass Sie kein 16-Bit-Register darin verschieben können. Sie müssen den Assembler zuerst als WORD (16 Bit) behandeln. Und zum Speichern der hohen 16 Bits, die in DX sind, müssen Sie sie nachAX im Speicher, also die +2. (Die +0 in der Zeile davor ist nur für die Symmetrie).

Nicht vergessen: Der 8086 speichert seine Multibyte-Werte mit den niedrigstwertigen Bytes zuerst. Das bedeutet, dass Sie die beiden Teile des Ergebnisses speichern müssen, wie ich oben gezeigt habe.

+0

Das OP verwendet eindeutig 32-Bit-Code aus C++ und ist nicht darauf beschränkt, auf 8086 zu laufen. Die Zwei-Operanden-Form von imul ist sehr praktisch. Außerdem wird der Assembler verwendet, der in MSVC++ integriert ist. Wie ich es verstehe, ist es ziemlich ähnlich wie MASM. –

+1

@PeterCordes Als ich die Frage das erste Mal sah, hatte sie: ein 8086-Tag; nur x86 Anweisungen; und nur ursprünglichen C++ Code. Diese letzten Änderungen ... Dinge ändern. Zu dir hinüber! –

+1

@Macmade D'oh! Ich kann nicht glauben, dass ich den Copy/Paste-Fehler so erleiden musste! Vielen Dank. –

Verwandte Themen