Seite 1 von 1
Quad, Probleme mit PeekB, Or, Shift ?
Verfasst: 25.01.2007 09:47
von IngolfZ
Bei der Portierung eines Moduls vom PB3 mit LongLongs zu PB4 mit Quads ist mir aufgefallen, dass es hier Probleme mit Quads gibt.
Im Folgenden habe ich mal die Kernprobleme extrahiert und allgemein gültig gemacht.
Code: Alles auswählen
Define qVar.q
Define lTmp.l
Define Daten.l
Daten = $44332211 ; zum Test, kein Byte ist für sich negativ!
; Im Speicher ist die Long wie folgt abgelegt:
; Daten+0 = $11
; Daten+1 = $22
; Daten+2 = $33
; Daten+3 = $44
qVar = PeekB(@Daten+2) | (PeekB(@Daten+1) << 8)
; qVar sollte jetzt den Wert $2233 haben (führende Nullen weggelassen)
Debug "(Falsch ) " + RSet(HexQ(qVar), 16,"0")
; In den höherwertigen Bits steht aber was :(
; Konstruktion mit Hilfs-Variable
lTmp = PeekB(@Daten+2) | (PeekB(@Daten+1) << 8) ; erst mal auf ein Long
qVar = lTmp ; dann dem Quad zuweisen
Debug "(Richtig) " + RSet(HexQ(qVar), 16,"0")
; qVar hat jetzt den Wert $2233
Bitte nicht über Sinn oder Unsinn dieses Codestückes diskutieren, es ist nur ein abstrahiertes Beispiel.
Stehe ich jetzt auf dem Schlauch oder hat hier PB4 ein Problem?
Verfasst: 25.01.2007 10:08
von NicTheQuick
Der Bug ist bekannt.
Ich weiß nur nicht mehr genau, in welchem Thread er schon aufgetreten ist.
Da muss ein Update her. Fragt sich nur noch, wann es kommt.
Verfasst: 26.01.2007 10:55
von mk-soft
Der Bug liegt in der Funktion HexQ().
Im Speicher liegt der richtige Quadwert. Uff
mk
Code: Alles auswählen
Define qVar.q
Define lTmp.l
Define Daten.l
Procedure.s HexQuad(Value.q, len = 0)
Protected i, temp.s
For i = 7 To 0 Step -1
temp + RSet(Hex(PeekB(@Value + i)), 2, "0")
Next
If len
temp = Right(temp, len)
EndIf
ProcedureReturn temp
EndProcedure
Daten = $44332211 ; zum Test, kein Byte ist für sich negativ!
; Im Speicher ist die Long wie folgt abgelegt:
; Daten+0 = $11
; Daten+1 = $22
; Daten+2 = $33
; Daten+3 = $44
qVar = PeekB(@Daten+2) | (PeekB(@Daten+1) << 8)
; qVar sollte jetzt den Wert $2233 haben (führende Nullen weggelassen)
Debug "(Falsch ) " + RSet(HexQ(qVar), 16,"0")
; In den höherwertigen Bits steht aber was :(
; Konstruktion mit Hilfs-Variable
lTmp = PeekB(@Daten+2) | (PeekB(@Daten+1) << 8) ; erst mal auf ein Long
qVar = lTmp ; dann dem Quad zuweisen
Debug "(Richtig) " + RSet(HexQ(qVar), 16,"0")
; qVar hat jetzt den Wert $2233
Debug "HexQuad: " + HexQuad(qVar)
Verfasst: 26.01.2007 12:53
von IngolfZ
Auf die Schnelle sind dir zwei Fehler unterlaufen:
1) nach PeekB in HexQuad musst du den Wert mit & $FF maskieren
2) Du hast in deinem Beispiel den "richtigen" Wert ausgegeben.
Wenn du das HexQuad Statement hinter das Debug "(Falsch)" setzt, wirst du sehen, dass der Wert im Speicher wirklich falsch ist.

Verfasst: 26.01.2007 13:04
von jear
@mk-soft
Der Bug liegt in der Funktion HexQ().
Im Speicher liegt der richtige Quadwert. Uff
Der Fehler leigt eindeutig in der Quad-Bearbeitung.
Beim Zuweisen erhält die Quad falsche Inhalte!
Die Funktion HexQ ist nicht fehlerhaft.
Allerdings hatte die HexQuad einen kleinen aber entscheidenden Fehler.
Das ist ein schwerwiegender Bug, der die ganze Quad-Bearbeitung in Frage stellt. Immer schön kontrollieren, was da rauskommt!
Code: Alles auswählen
Define qVar.q
Define lTmp.l
Define Daten.l
Procedure.s HexQuad(Value.q, len = 0)
Protected i, temp.s
For i = 7 To 0 Step -1
temp + RSet(Hex(PeekC(@Value + i)), 2, "0") ; kein PeekB! Achtung Vorzeichen!
Next
If len
temp = Right(temp, len)
EndIf
ProcedureReturn temp
EndProcedure
Daten = $44332211 ; zum Test, kein Byte ist für sich negativ!
; Im Speicher ist die Long wie folgt abgelegt:
; Daten+0 = $11
; Daten+1 = $22
; Daten+2 = $33
; Daten+3 = $44
qVar = PeekB(@Daten+2) | (PeekB(@Daten+1) << 8)
; qVar sollte jetzt den Wert $2233 haben (führende Nullen weggelassen)
Debug "(Falsch ) HexQ: " + RSet(HexQ(qVar), 16,"0")
; In den höherwertigen Bits steht aber was :(
Debug "(Falsch) HexQuad: " + HexQuad(qVar)
; Quad demaskieren
qVar & $FFFFFFFF
Debug "(Richtig) HexQuad: " + HexQuad(qVar)
; Konstruktion mit Hilfs-Variable
lTmp = PeekB(@Daten+2) | (PeekB(@Daten+1) << 8) ; erst mal auf ein Long
qVar = lTmp ; dann dem Quad zuweisen
Debug "(Richtig) HexQ: " + RSet(HexQ(qVar), 16,"0")
; qVar hat jetzt den Wert $2233
Debug "(Richtig) HexQuad: " + HexQuad(qVar)
Verfasst: 26.01.2007 13:17
von Kaeru Gaman
sowas... also sind die dinger unbrauchbar.
ich hab gehört, das seien keine nativen Quads, sondern die würden mit ner struct emuliert...
kann das stimmen? kann das damit zusammenhängen?
auf jeden Fall muss da Fred nochmal bei, da leckt noch Öl raus....
Verfasst: 26.01.2007 16:37
von mk-soft
Ein ähnliches Problem gibt es auch hier
http://www.purebasic.fr/german/viewtopic.php?t=11422
Lag glaub ich daran das von der Unterfunktion (Peekb(), Scroll, etc) ein Register zerschossen wird welche bei Quads benötigt wird.
Ist als Bug schon gemeldet worden.
An der Funktion HexQ() lag es nicht. Hab mich getäuscht.

Verfasst: 26.01.2007 20:15
von Helle
Habe mir den ASM-Output angeschaut und keinen Fehler gefunden. In der Quad-Variable landet der richtige Wert. Ursache für die falsche Ausgabe ist der zugeschaltete Debugger. Wird der ausgeschaltet und die Ausgabe über Messagerequester gemacht ist alles in Ordnung. Da muss jetzt aber wirklich jemand vom PB-Team ran!
Die "Zusatzzahl" ist übrigens die Speicheradresse von Daten+1.
BTW:
bringt mich stark ins Grübeln. Prioritäten hin und her, ich hätte jetzt erwartet, das der eingelesene Byte-Wert geshiftet wird und dann erst weiterverarbeitet wird.
Gruss
Helle
Verfasst: 04.02.2007 16:06
von Andre
Für alle Fälle - ich habe Fred & freak nochmal auf diesen Thread hingewiesen.