Autor Thema: Seltsamer Opcode von loop  (Gelesen 4173 mal)

[MM]

  • Beiträge: 130
    • Profil anzeigen
    • www.mmcoding.eu
Gespeichert
« am: 17. February 2006, 01:09 »
Hallo, ich habe heute mit erstaunen festgestellt, dass beim loop Befehl die Bedeutung der Prefix-Bytes offenbar umgedreht zu sein scheint:
Dieser Code geht nur ein mal durch die Schleife (ich gehe von einem 16-Bit Codesegment aus (gelöschtes D-Bit) oder im RealMode):
mov ecx,0x10001
mark:
loop mark ; Mit Prefix 0x66


Dieser Code geht 0x10001 mal durch die Schleife:
mov ecx,0x10001
mark:
loop mark ; Mit Prefix 0x67


Laut Intel ist der Prefix 0x66 für Operand Size Overrides und 0x67 für Address Size Overrides. Warum wird also wenn ich ecx ansprechen will der Prefix für das Ändern der Adressgröße verwendet und nicht das für den Operand?

Damit ist aber noch nicht genug: Wenn ich das Loop in einem Codeteil verwenden will der an einer Adresse über 0xFFFF liegt, so muss ich den Prefix 0x66 (zusätzlich) verwenden. Ich hätte die Belegung der beiden Präfixe genau umgekehrt erwartet.

Könnte da Jemand zur Klärung beitragen?

MM

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #1 am: 17. February 2006, 14:02 »
Hmm... Also der Code ist ja von beiden gleich. Der Assembler übersetzt ihn auch gleich. Also das was du sagst kann nicht stimmen. Dem Assembler interessiert den Modus (PM oder RM) nämlich nicht. Und im RealMode können auch 32 Bit Register benutzt werden. Hast du in einem Assembler aber 32 Bit Code angegeben so wird nur dann ein präfix drangesetzt wenn es 16 Bit sein soll. Wenn du 16 Bit Code angibst dann wird nur ein präfix drangehangen wenn du 32 Bit Code nutzt (also genau umgekehrt).

bitmaster
In the Future everyone will need OS-64!!!

[MM]

  • Beiträge: 130
    • Profil anzeigen
    • www.mmcoding.eu
Gespeichert
« Antwort #2 am: 17. February 2006, 15:50 »
Der Code ist bei beiden nicht gleich, deshalb habe ich ja dazu geschrieben welches Prefixbyte ich benutz habe:
Mit Prefix 0x66:
0F10:0100 66B901000100    mov     ecx,00010001
0F10:0106 66E2FD          loop    0106


Mit Prefix 0x67:
0F10:0100 66B901000100    mov     ecx,00010001
0F10:0106 67E2FD          loop    0106


Und die Frage bezieht sich auch nicht auf einen bestimmten Assembler sondern DIREKT auf den Opcode. Mich interessiert also nicht, ob zB der masm das automatisch richtig macht oder so, sondern wie ich sagte: warum der "Address Size Override" benutzt wird um ecx anstelle von cx zu benutzen.

MM

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #3 am: 17. February 2006, 17:29 »
@MM: Ach so, ja ich habe es gerade getestet. Der TASM macht auch ein 67h davor wenn ich loopd benutze. Ich versuche mal mit meinem Hexeditor das 67h durch das 66h zu ersetzten. Mal sehen was passiert. ;)

bitmaster

EDIT: nee, wie erwartet funktioniert es mit 66h nicht. KA warum das 67h sein muss.
In the Future everyone will need OS-64!!!

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #4 am: 17. February 2006, 17:41 »
Obwohl mir gerade einfällt das man mit loop sowohl ein Register als auch eine Adresse benutzt. Intel hat hier warscheinlich den Adress-Size Präfix genommen, weil man ja auch dann eine 32Bit Adresse anspringen kann.

bitmaster
In the Future everyone will need OS-64!!!

SK-Genius

  • Beiträge: 8
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 17. February 2006, 18:53 »
Zitat
"Operand-size override"
Umschalten zwischen 16 und 32-Bit Operanten. Wechselt dabei zum non-Default wert.


ich würde da mal empfehlen herrauszufinden welches der default wert ist. also was pasiert wenn man den prefix weg lässt.

edit:
zb durch ersetzen des prefixes durch ein nop (0x90) mit einem hexeditor.

[MM]

  • Beiträge: 130
    • Profil anzeigen
    • www.mmcoding.eu
Gespeichert
« Antwort #6 am: 17. February 2006, 20:00 »
Im Real-Mode sind 16-Bit Daten und Adressen Default. Im Protected-Mode wird das durch das D-Bit im Codedescriptor bestimmt.
Beispiel aus dem Real-Mode:
2477:0100 66B800000000    mov     eax,00000000
Wie man hier gut sehen kann wird der Operand Size Override (0x66) benutzt um anstelle von ax auf eax zuzugreifen. läßt man ihn weg wird der Befehl als mov ax,0 interpretiert (wodurch aber 2x 0x00 dahinter übrig wären...).

Und ich würde für solche Experimente auch nicht unbedingt einen Hexeditor nehmen, sondern einen 32-Bit Debugger (ich würde den DDEB empfehlen).

@bitmaster:
Ja, die Idee hatte ich auch schon, dass ja sowohl ein Register als auch eine Adresse daran beteiligt sind, jedoch finde ich es trotzdem unlogisch dann mit der 0x67 dafür zu sorgen ecx zu benutzen und nicht wie bei jedem anderen Befehl mit der 0x66.

MM

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #7 am: 18. February 2006, 01:12 »
Zitat von: [MM]
jedoch finde ich es trotzdem unlogisch dann mit der 0x67 dafür zu sorgen ecx zu benutzen und nicht wie bei jedem anderen Befehl mit der 0x66.
Beschwere dich bei Intel. ;)

bitmaster
In the Future everyone will need OS-64!!!

 

Einloggen