Seite 1 von 1

[ASM] Out of Range - Bug?

Verfasst: 05.08.2015 18:08
von 7x7
Kann mir einer erklären, warum der Compiler(x64) hier meckert?

Code: Alles auswählen

EnableASM

MOV rax, $FFFFFFFFFFFFFFFF	;funktioniert

AND rax, $FFFFFFFF			;Out of Range?????
"AND" kann man genauso gut durch XOR, OR usw. ersetzen....alles fail! :freak:


Aber DAS hier funktioniert:

Code: Alles auswählen

AND rax, $FFFFFFFFFFFFFFFF
:lol:
PB 5.24 LTS
Edit by NicTheQuick: Threadtitel angepasst

Re: Bug?

Verfasst: 05.08.2015 18:32
von NicTheQuick
Wäre das jetzt x86, hätte ich es mir noch dadurch erklären können, dass alles über $7FFFFFFF negativ ist. In der Tat geht nämlich dieser Code hier:

Code: Alles auswählen

And rax, $7FFFFFFF
Als ob er die Zahl als Long interpretiert, sie dadurch als negative Zahl interpretiert wird, und er dann eben meckert.
Das erklärt aber nicht, warum $FFFFFFFFFFFFFFFF funktioniert.

Vielleicht kannst du dir mit einer Konstanten behelfen:

Code: Alles auswählen

a.i = $FFFFFFFF
#b = $ffffffff

And rax, a
And rax, #b

Re: [ASM] Out of Range - Bug?

Verfasst: 05.08.2015 22:01
von Helle
Nee, ist kein Bug :) ! Wichtig ist zu wissen, das für aktuelle (AMD-/Intel-) CPUs (x86, x64 oder sonstwas) der an die CPU für eine Instruktion übergebene Opcode max. 15 Bytes lang sein darf. Im 64-Bit-Modus ergäben sich aber schnell längere Sequenzen (zusätzliche Prefixe, direkte Adressierung 8 Bytes usw.). Dies wird durch Restriktionen verhindert; eben z.B. das nur MOV Register64 mit einem 64-Bit-Wert erlaubt ist. ALLE anderen Operationen sind auf einen positiven 32-Bit-Wert begrenzt. Aber natürlich keine Regel ohne Ausnahmen, wobei diese Ausnahmen Eigenheiten der Opcode-Codierung widerspiegeln. Erlaubt sind Werte-Kombinationen, die max.4 Byte (Wert) lang sind, aber real längere Werte repräsentieren. Also, wer denkt, das

Code: Alles auswählen

AND  RAX , FFFFFFFFFFFFFFFF
im Opcode mit 16x "F" daherkommt, der irrt. Der Opcode lautet nämlich simple

Code: Alles auswählen

48 83 E0 FF
Die Regeln dafür sind rel. simpel (z.B. AND RAX , EFFFFFFFFFFFFFFF würde nicht funktionieren), aber meine Empfehlung: Nur MOV mit 64-Bit-Werten, ansonsten Zwischenschritt eben mit MOV und Hilfs-Register zwischenschalten. Und: Was mit Register RAX (EAX) funktioniert, kann mit anderen Registern schon schief gehen (RAX/EAX haben mitunter eigenen Opcode).

Gruß
Helle

Re: [ASM] Out of Range - Bug?

Verfasst: 05.08.2015 22:33
von NicTheQuick
Cool, super Antwort! Danke!

Re: [ASM] Out of Range - Bug?

Verfasst: 06.08.2015 14:30
von 7x7
Danke Helle! Du machst deinem Namen alle Ehre ;-)

(Ich war in den '80ern mal bei Control Data/Frankfurt. Da kannte ich auch einen "Helmut aus Magdeburg" (Nachnamen leider vergessen). Warst das vielleicht du?)

Re: [ASM] Out of Range - Bug?

Verfasst: 07.08.2015 16:49
von Helle
Ich nix Helmut, ich Helle :mrgreen: ! Ist von meinem Nachnamen abgeleitet, und das schon seit Beginn der Schulzeit. Und das ist weiß Gott schon etwas her... :)
Aber nochmal Richtung Topic 64-Bit: Nicht nur die Immediates sind auf 4 Bytes begrenzt (MOV s.o.), auch z.B.Sprungadressen. Bei 32-Bit kann man die Sprung-Ziel-Adresse im Code noch direkt auslesen. Bei 64-Bit könnte die ja (muss nicht!) größer 4 Bytes sein. Also hat man dort die relative Adressierung mit 4 Bytes eingeführt. Es wird nicht mehr die tatsächliche Adresse verwendet, sondern der Offset von Sprung-Ausgang zu Sprung-Ziel; d.h. das Sprung-Ziel muss erst berechnet werden.

Gruß
Helle