Frage

Ich lerne 80386 von PC Montage von paul caurter

  mul source
  
      
  • Wenn der Operand Byte bemessen ist, wird es durch das Byte in der AL multipliziert   registrieren und die Ergebnis wird gespeichert in   die 16 Bits von AX .
  •   

in Ordnung.

  
      
  • Wenn die Quelle 16-Bit ist, wird es durch das Wort in AX multipliziert und dem   32-Bit-Ergebnis wird in DX gespeichert. AX
  •   

Q1: Warum DX: AX? Warum kann es nicht speichern, in EAX / EDX?

imul wirklich verwirrend

imul dest, source1
imul dest, source1, source2

Ich habe Probleme in der Tabelle zu verstehen.

Q2: in dem 2. Eintrag der Tabelle. Wieder warum DX: AX. Warum nicht EAX oder EDX?

Jetzt folgende Code-Schnipsel betrachten:

imul eax ; edx:eax = eax * eax
mov ebx, eax ; save answer in ebx
mov eax, square_msg ; square_msg db "Square of input is ", 0
call print_string ; prints the string eax
mov eax, ebx 
call print_int ;  prints the int stored in eax
call print_nl ; prints new line

Q3: Das sagt previsously dass The notation EDX:EAX means to think of the EDX and EAX registers as one 64 bit register with the upper 32 bits in EDX and the lower bits in EAX. So ist die Antwort auch in edx gespeichert ist, nicht wahr? in dem obigen Code haben wir keine EDX nicht betrachten wir nur mit Bezug auf EAX sind Wie wird dies noch funktioniert?

Q4: Ich habe Problem mit dem Rest aller Einträge in der Tabelle. Worst-Case-Multiplikationser von zwei n-Bit-Zahlen (n = 8/16/32 Bit) ist 2n Bits. Wie kommt es seine Speichern des Ergebnisses von zwei 16/32 Bit Multiplikationsergebnis im Register der gleichen Größe selbst?

War es hilfreich?

Lösung

Q1 / Q2: Der x86-Befehlssatz behält seine 16-Bit-Geschichte. Wenn mehrfach ein 16-Bit zu tun, ist die Antwort im DX gespeichert: AX. Das ist einfach so, wie es ist, weil das ist, wie es in 16-Bit-Land war.

Q3. Der Code, den Sie zeigte hat einen Fehler, wenn Sie versuchen, das Quadrat einer Zahl zu berechnen, die größer als 2 ^ 16, weil der Code die hohen 32 Bits des Ergebnisses in edx gespeichert ignoriert

Q4: Ich glaube, Sie können die Tabelle werden Verlesen. 8-Bit-Multiplikationen werden in einem 16-Bit-Ergebnis gespeichert wird; 16-Bit-Multiplikationen werden in einem 32-Bit-Ergebnis gespeichert wird; 32-Bit-Multiplikationen werden in einem 64-Bit-Ergebnis gespeichert. Welche Linie beziehen Sie sich konkret?

Andere Tipps

Es gibt viele verschiedene Varianten des IMUL instruction.2 Bit-Code.

Die Variante Sie auf gestolpert ist eine 16-Bit-Multiplikation. Es multipliziert das AX-Register mit dem, was Sie passieren als Argument für IMUL und speichert das Ergebnis in DX:. AX

Eine 32-Bit-Variante funktioniert wie die 16-Bit-Multiplikation, sondern schreibt das Register in EDX: EAX. Zur Nutzung dieser Variante alles, was Sie tun müssen, ist ein 32-Bit-Argument zu verwenden.

Z. B:

  ; a 16 bit multiplication:
  mov ax, [factor1]
  mov bx, [factor2]
  imul bx              ; 32-bit result in DX:AX
  ; or  imul  word [factor2]

  ; a 32 bit multiplication:
  mov eax, [factor1]
  mov ebx, [factor2] 
  imul ebx             ; 64-bit result in EDX:EAX

Auf einem 386 oder höher können Sie auch eine imul in die beiden schreiben Operanden bilden. Das macht es sehr viel flexibler und einfacher zu arbeiten. Bei dieser Variante können Sie all 2-Register als Quelle und Ziel frei wählen, und die CPU wird nicht Zeit mit dem Schreiben eines hohes Halbjahresergebnis überall verschwenden. Und wird nicht EDX zerstören.

  mov   ecx, [factor1]
  imul  ecx, [factor2]    ; result in ecx, no other registers affected
  imul  ecx, ecx          ; and square the result

oder für 16-Bit-Eingänge Ihre imul übereinstimmen. (Verwendung movzx für unsigned Eingänge)

  movsx   ecx, word [factor1]
  movsx   eax, word [factor2]  ; sign-extend inputs to 32-bit
  imul    eax, ecx             ; 32-bit multiply, result in EAX
  imul    eax, eax             ; and square the result

Diese Variante von IMUL war mit 386 eingeführt und verfügbar in 16 und 32-Bit-Operanden-Grße. (Und 64-Bit-Operanden-Größe in 64-Bit-Modus).

In 32-Bit-Code kann man immer davon ausgehen, dass 386 Befehle wie imul reg, reg/mem verfügbar sind, aber Sie können es in 16-Bit-Code verwenden, wenn Sie über älteren CPUs egal.

286 eingeführt, um eine 3-Operanden unmittelbare Form.

imul  cx, bx, 123        ; requires 286

imul  ecx, ebx, 123      ; requires 386
  

Q1 / Q2: Warum DX: AX? Warum kann es nicht speichern, in EAX / EDX?

Wie schon andere gesagt, das ist nur für Abwärtskompatibilität . Die ursprünglichen (i)mul Anweisungen sind von 16-Bit-x86, die gekommen waren, lang , bevor der 32-Bit-x86-Befehlssatz erschien, so dass sie nicht das Ergebnis der EAX / EDX speichern könnten, da war keine E-Register .

  

Q3: im obigen Code betrachten wir fanden keine EDX beziehen wir uns nur auf EAX Wie ist das noch funktioniert

Sie haben kleine Werte eingegeben, um das Ergebnis zu Überlauf verursachen nicht, so dass Sie die Unterschiede nicht gesehen haben. Wenn Sie groß genug, um Werte (> = 16 Bit) verwenden, werden Sie sehen, dass EDX! = 0 und das gedruckte Ergebnis falsch sein wird.

  

Q4: Wie kommt es sein das Ergebnis von zwei 16/32 Bit Multiplikationsergebnis im Register der gleichen Größe zu speichern selbst

Es ist nicht, dass das Ergebnis immer noch die gleiche Größe als die Operanden. Multipliziert zwei n-Bit-Werte erzeugt immer einen 2n-Bit-Wert . Aber in imul r16, r/m16[, imm8/16] und ihre 32/64-Bit-Pendants die hohen n-Bit-Ergebnisse werden verworfen. Sie werden verwendet, wenn Sie nur brauchen, um die unteren 16/32/64 Bits des Ergebnisses (dh nicht Multiplikation Erweiterung) oder wenn können Sie sicherstellen, dass das Ergebnis nicht überläuft.

  
      
  • Zwei-Operanden-Form - Bei dieser Form der Zieloperand (der erste Operand) wird durch die Quelloperand (zweiter Operand) multipliziert. Der Zieloperand ist ein Universalregister und der Quelloperand ist ein Zwischenwert, ein Universalregister oder eine Speicherstelle. Das Zwischenprodukt (das Zweifache der Größe des Eingangsoperanden) wird abgeschnitten und in den Zieloperanden Stelle gespeichert.
  •   
  • [... Das Gleiche gilt für Drei-Operanden-Form]
  •   
     

https://www.felixcloutier.com/x86/IMUL.html

Moderne Compiler heutzutage fast ausschließlich verwenden, um die Multi-Operanden imul für beide mit und ohne Vorzeichen Multiplikationen, weil

Q1 / Q2: Ich denke, der Grund, historisch. Vor dem 32-Bit-Option war, gab es keine EAX oder edx. Die 32-Bit-Funktionalität wurde hinzugefügt rückwärtskompatibel zu sein.

Q3: Die niederwertigen Bits werden in EAX sein. Das sind die einzigen, die sich um dich kümmern, wenn nicht Überlauf in die High-Bits gibt.

Q4: Auf jeden Fall eine ungerade Tabelle. Ich glaube, Sie bekommen es aber.

A1: war mul die ursprünglich an den 8086/8088/80186/80286 Prozessoren, die nicht die E haben ** (E für längere, dh 32 Bit) Register

A2:. Siehe A1

Als meine Arbeit als Assembler-Programmierer auf die Motorola 680x0-Familie vor diesem Gemeinplatz wurde Intels 32-Bit bewegt, ich werde aufhören: -)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top