Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

Binary Get und sein Hex-Wert
Gehe zu Seite 1, 2  Weiter
 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Digga



Anmeldungsdatum: 07.01.2006
Beiträge: 48

BeitragVerfasst am: 21.07.2009, 22:10    Titel: Binary Get und sein Hex-Wert Antworten mit Zitat

Hallo alle zusammen.

Hab ein kleines Problem. Und zwar möchte ich Werte Binär aus einer Datei lesen. Solange ich dies mit Byte als Datentyp mache,
klappt es auch wunderbar. Nur so bald ich Als Datentyp Integer benutze kommt ein ganz anderer Wert raus.

Wert in der Datei =

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000 24 3D F9 E7

Doch das Programm sagt: E7F93D24

Code:

DIM Zahl AS UINTEGER
DIM file AS UINTEGER = FREEFILE

OPEN "test.dat" FOR BINARY AS #file
   GET #file,  , Zahl
CLOSE #file
PRINT HEX(Zahl)



Wäre schön wenn jemand mir weiterhelfen kann. Komme sonst nicht weiter.

Gruß Digga
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
St_W



Anmeldungsdatum: 22.07.2007
Beiträge: 956
Wohnort: Austria

BeitragVerfasst am: 21.07.2009, 22:28    Titel: Antworten mit Zitat

Intel Prozessoren arbeiten mit der Byte-Anordnung Little Endian.

Mehr dazu auf Wikipedia unter http://de.wikipedia.org/wiki/Byte-Reihenfolge

Vielleicht helfen dir folgende Funktionen:
Code:
'Interpretiert einen String als Zahl im BigEndian Format
Function Str2IntBE(ByRef tmpStr As String) As UInteger
    Dim q As UInteger
    Dim w As UInteger = 0
    Dim l As Integer = Len(tmpStr)
    For q = 1 To l
        w = w Or (Asc(Mid(tmpStr,q,1)) Shl ((l-q)*8))
    Next
    Return w
End Function

'Interpretiert einen String als Zahl im LittleEndian Format
Function Str2IntLE(ByRef tmpStr As String) As UInteger
    Dim q As UInteger
    Dim w As UInteger = 0
    Dim l As Integer = Len(tmpStr)
    For q = 1 To l
        w = w Or (Asc(Mid(tmpStr,q,1)) Shl ((q-1)*8))
    Next
    Return w
End Function

'Stellt eine Zahl als String im BigEndian Format dar
'(Laenge = Länge der Zeichenkette, links mit 0 aufgefüllt. Laenge = 0 --> benötigte Länge)
Function Int2StrBE(ByVal tmpInt As UInteger, ByVal Laenge As Integer = 0) As String
   Dim q As Integer = 0
   Dim tmpStr As String = ""
   Do
      tmpStr = Chr((tmpInt Shr q*8) And &b11111111) + tmpStr
      q += 1
      If (tmpInt Shr (q*8)) = 0 Then Exit Do
   Loop
   If Laenge > 0 Then tmpStr = RPad(tmpStr,0,Laenge)
   Return tmpStr
End Function


'Stellt eine Zahl als String im LittleEndian Format dar
Function Int2StrLE(ByVal tmpInt As UInteger, ByVal Laenge As Integer = 0) As String
   Dim q As Integer = 0
   Dim tmpStr As String = ""
   Do
      tmpStr += Chr((tmpInt Shr q*8) And &b11111111)
      q += 1
      If (tmpInt Shr (q*8)) = 0 Then Exit Do
   Loop
   If Laenge > 0 Then tmpStr = RPad(tmpStr,0,Laenge)
   Return tmpStr
End Function


'//edit: Achja, folgende Funktionen werden von den obigen zwei benötigt:

Declare Function LPad OverLoad (Daten As String, PadZeichen As String, Laenge As Integer) As String
Declare Function LPad(Daten As String, PadZeichen As Integer, Laenge As Integer) As String

Declare Function RPad OverLoad (Daten As String, PadZeichen As String, Laenge As Integer) As String
Declare Function RPad(Daten As String, PadZeichen As Integer, Laenge As Integer) As String


Function LPad(Daten As String, PadZeichen As String, Laenge As Integer) As String
   Return LPad(Daten, Asc(PadZeichen), Laenge)
End Function

Function LPad(Daten As String, PadZeichen As Integer, Laenge As Integer) As String
   If Len(Daten) = Laenge Then Return Daten
   If Len(Daten) > Laenge Then Return Left(Daten, Laenge)
   Return Daten & String(Laenge - Len(Daten), PadZeichen)
End Function

Function RPad(Daten As String, PadZeichen As String, Laenge As Integer) As String
   Return RPad(Daten, Asc(PadZeichen), Laenge)
End Function

Function RPad(Daten As String, PadZeichen As Integer, Laenge As Integer) As String
   If Len(Daten) = Laenge Then Return Daten
   If Len(Daten) > Laenge Then Return Left(Daten, Laenge)
   Return String(Laenge - Len(Daten), PadZeichen) & Daten
End Function


_________________
Aktuelle FreeBasic Builds, Projekte, Code-Snippets unter http://users.freebasic-portal.de/stw/
http://www.mv-lacken.at Musikverein Lacken (MV Lacken)


Zuletzt bearbeitet von St_W am 22.07.2009, 02:03, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 21.07.2009, 22:40    Titel: Antworten mit Zitat

50% Chance, 100% Falsch. Zunge rausstrecken Die x86-Architektur ist so ziemlich die einzige LittleEndian-Architektur, die heute noch lebt...
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
St_W



Anmeldungsdatum: 22.07.2007
Beiträge: 956
Wohnort: Austria

BeitragVerfasst am: 22.07.2009, 02:06    Titel: Antworten mit Zitat

Ooops verlegen

Intel is natürlich Little Endian und Motorola is Big Endian.

(Habs wahrscheinlich verwechselt, da ich in letzter Zeit mit dem ganzen ID3, EXIF, etc. Zeugs überwiegend BigEndian gebraucht hab. An dieser Stelle: EXIF-(Lese)-Unterstützung für mein Projekt Multimedia-Tag is schon in der Testphase)
_________________
Aktuelle FreeBasic Builds, Projekte, Code-Snippets unter http://users.freebasic-portal.de/stw/
http://www.mv-lacken.at Musikverein Lacken (MV Lacken)
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Digga



Anmeldungsdatum: 07.01.2006
Beiträge: 48

BeitragVerfasst am: 22.07.2009, 16:14    Titel: Antworten mit Zitat

Hallo.

Danke für deinen Hinweis und die Hilfe St_W.

Habe es jetzt so gelöst:

Code:

DIM Zahlgross AS UINTEGER
DIM Zahlklein  AS UBYTE
DIM file AS UBYTE = FREEFILE
DIM Index AS UBYTE = 1

OPEN "test.dat" FOR BINARY AS #file
    DO UNTIL (Index = 5)
       GET #file,  , Zahlklein
       Zahlgross += Zahlklein * (256^(4 - Index))
       Index += 1
    LOOP
CLOSE #file


Geht zwar auch bestimmt schneller, aber für meine zwecke wird es erst einmal ausreichen.

Zur Erläuterung, ich möchte eine Datei auslesen in der Dateiinterne Adressen gespeichert sind.
Wenn ich sie einfach so eingelesen hätte wäre alles raus gekommen,
nur nicht das was ich will...

gruß Digga
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 22.07.2009, 16:24    Titel: Antworten mit Zitat

Also Endian-Konvertierung mit Potenzen zu lösen ist doof und langsam. FreeBASIC kann doch sogar Bitshifting (SHR, SHL), nimm lieber das.

Könnte z.B. so gehen:

Code:

dim as integer gesamtwert = 0, bytewert
For i as integer = 0 to 4
  get #file,, bytewert
  gesamtwert = (gesamtwert shl 8) + bytewert
next

_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Digga



Anmeldungsdatum: 07.01.2006
Beiträge: 48

BeitragVerfasst am: 22.07.2009, 17:11    Titel: Antworten mit Zitat

Stimmt das geht ja auch mit dem Kopf durch die Mauer wollen

bytewert muss in dem Fall aber vom Typ Byte sein, sonst kommt da ein ganz
anderer Wert raus

Code:

dim as integer gesamtwert = 0
dim as byte  bytewert
For i as integer = 0 to 4
  get #file,, bytewert
  gesamtwert = (gesamtwert shl 8) + bytewert
next


Ansonsten klappt es wunderbar. Danke schon.

gruß Digga
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
volta



Anmeldungsdatum: 04.05.2005
Beiträge: 1876
Wohnort: D59192

BeitragVerfasst am: 22.07.2009, 18:14    Titel: Antworten mit Zitat

Code:
'Es gibt zwei Formen der Speicherorganisation,
'sie nennen sich Little Endian und Big Endian.
'Little Endian findet vor allem bei x86-Prozessoren Anwendung,
'Big Endian bei den 68000 von Motorola (Apples Macintosh)
'sowie bei vielen RISC-Prozessoren.
'Little Endian zeichnet sich dadurch aus, dass der niederwertigste Teil
'eines Datums im Speicher an der niedrigsten Adresse steht.
'Bei Big Endian verhält es sich genau umgekehrt.
'Adresse  Little Endian     Big Endian
' + 0        Byte 0           Byte 3
' + 1        Byte 1           Byte 2
' + 2        Byte 2           Byte 1
' + 3        Byte 3           Byte 0
'Durch tauschen von Byte 0 mit Byte 3 sowie Byte 1 mit Byte 2
'kann man von Little Endian nach Big Endian oder umgekehrt konvertieren.
'Die entsprechende ASM-Anweisug nennt sich BSWAP
#Macro BSWAP32(a)
  Asm
    mov eax, [a]
    bswap eax
    mov [a], eax
  End Asm
#EndMacro

DIM AS INTEGER gesamtwert
GET #file,, gesamtwert
BSWAP32(gesamtwert)

_________________
Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 22.07.2009, 22:49    Titel: Antworten mit Zitat

@Digga: Sorry, war ungetestet. Aber gut, dass du den Fehler aufgedeckt hast, das zeigt dass du dich damit befasst und es verstanden hast. lächeln

@Volta: Ich persönlich würde auf den Einsatz von ASM aus Portierbarkeitsgründen hier verzichten. Im OpenMPT-Code haben wir folgende Makros, sollte sich ja leicht auf FB übertragen lassen:

Code:
#ifdef PLATFORM_BIG_ENDIAN
// PPC
inline DWORD LittleEndian(DWORD x)   { return ((x & 0xFF) << 24) | ((x & 0xFF00) << 8) | ((x & 0xFF0000) >> 8) | ((x & 0xFF000000) >> 24); }
inline WORD LittleEndianW(WORD x)   { return (WORD)(((x >> 8) & 0xFF) | ((x << 8) & 0xFF00)); }
#define BigEndian(x)            (x)
#define BigEndianW(x)            (x)
#else
// x86
inline DWORD BigEndian(DWORD x)   { return ((x & 0xFF) << 24) | ((x & 0xFF00) << 8) | ((x & 0xFF0000) >> 8) | ((x & 0xFF000000) >> 24); }
inline WORD BigEndianW(WORD x)   { return (WORD)(((x >> 8) & 0xFF) | ((x << 8) & 0xFF00)); }
#define LittleEndian(x)         (x)
#define LittleEndianW(x)      (x)
#endif

_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
28398



Anmeldungsdatum: 25.04.2008
Beiträge: 1917

BeitragVerfasst am: 22.07.2009, 23:06    Titel: Antworten mit Zitat

FBC gibbet erst für x86...

Und BSWAP gibt es ab i486...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 22.07.2009, 23:21    Titel: Antworten mit Zitat

Zitat:
FBC gibbet erst für x86...

die unteren Makros kann man ja trotzdem verwenden. lächeln
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
28398



Anmeldungsdatum: 25.04.2008
Beiträge: 1917

BeitragVerfasst am: 23.07.2009, 01:26    Titel: Antworten mit Zitat

Sind aber DEUTLICH langsamer. BSWAP wird vermutlich bei neueren Prozis mit einem oder zwei Takten abgearbeitet. Deine Makros?
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 23.07.2009, 09:47    Titel: Antworten mit Zitat

Den richtigen Compiler gegeben, wird er auf x86-Platformen höchstwahrscheinlich etwas wie bswap verwenden. Und ich hoffe du bist dir über die Geschwindigkeit von logischen Operationen wie & oder << im Klaren...
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
28398



Anmeldungsdatum: 25.04.2008
Beiträge: 1917

BeitragVerfasst am: 23.07.2009, 15:49    Titel: Antworten mit Zitat

FBC hat noch keinen "richtigen" Optimierer. Und selbst die logischen Ops brauchen jeweils mindestens einen Takt. Zzgl. den Code um das mit den Klammern umzusetzen.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 23.07.2009, 15:58    Titel: Antworten mit Zitat

Ein Prozessor kennt keine Klammern... Der führt das nur in der richtigen Reihenfolge aus. Zunge rausstrecken
Außerdem, wer sagt dir dass BSWAP atomar ist, also wirklich nur einen Taktyklus benötigt?
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
St_W



Anmeldungsdatum: 22.07.2007
Beiträge: 956
Wohnort: Austria

BeitragVerfasst am: 23.07.2009, 22:28    Titel: Antworten mit Zitat

@Jojo,28398: Es kommt ja immer wieder vor, dass ihr zwei euch gegenseitig mit (mehr oder weniger) sinnvollen Beiträgen von eurer Meinung überzeugen wollt (was ja solang es sachlich bleibt nichts Schlechtes ist). Normalerweise möchte ich mich ja in sowas nicht einmischen, aber dieses Mal muss ich doch 283.. Recht geben:

BSWAP ist definitiv schneller, benötigt weniger Speicherplatz, und einfacher zu verstehen, .., als ein paar SHL, AND, OR, ...

Code:
FreeBasic macht z.B. aus

((x shr 8) and &HFF) or ((x shl 8) and &HFF00)

den folgenden Assemblercode:
(sinngemäß vereinfacht, einige zusätzliche MOV, PUSH & POP entfernt)

shr eax, 8
and eax, 255
shl ebx, 8
and ebx, 65280
or eax, ebx


Auf einem Intel 80486er Prozessor benötigt BSWAP 2 Bytes Speicherplatz und einen (1) Takt zur Ausführung.

Obiges Beispiel im Vergleich:
shr reg,const 3 Takte, 2 Bytes
and reg,const 1 Takt, 3 Bytes
shl reg,const 3 Takte, 2 Bytes
and ebx,const 1 Takt, 3 Bytes
or reg,reg 1 Takt, 2 Bytes
===========================
9 Takte, 12 Bytes

Welches von den beiden da einfacher, schneller und Speicherplatzschonender ist muss ich wohl kaum noch ausführlich erleutern...
(Lasset die Flut von Gegenargumenten beginnen... durchgeknallt )
_________________
Aktuelle FreeBasic Builds, Projekte, Code-Snippets unter http://users.freebasic-portal.de/stw/
http://www.mv-lacken.at Musikverein Lacken (MV Lacken)
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 23.07.2009, 22:43    Titel: Antworten mit Zitat

Einfaches Gegenargument: Läuft nur auf x86-Plattformen. Gerade durch die Entwicklung von OpenMPT / libmodplug (und auch die Vorlesung Rechnersysteme Zunge rausstrecken) wurde ich auf so Plattformabhängigkeiten aufmerksam. Es mag sein, dass FB im Moment nur für x86 existiert, aber Sourcecode sollte immer so zukunftssicher wie eben möglich sein - Von daher, bei so trivialen dingen lieber gleich alles so machen, wie es auch noch in fünf Jahren funktionieren wird!
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
volta



Anmeldungsdatum: 04.05.2005
Beiträge: 1876
Wohnort: D59192

BeitragVerfasst am: 24.07.2009, 00:12    Titel: Antworten mit Zitat

Jojo, zieh die Brense ... zwinkern

In anderen Sprachen mag diese Art Portierbarkeit ihre Berechtigung haben.
In Freebasic mache ich mir in punkto Portierbarkeit höchstens Gedanken ob es noch in älteren oder neueren Versionen (auch Win-Versionen) kompiliert wird.
Sicher, BSWAP läuft nur auf x86-Pattform, dort habe ich damit eine schnelle Möglichkeit zu konvertieren.
Auf Plattformen die im Big Endian-Format lesen brauche ich diese Anweisung nicht. Die müssen sich entsprechendes für Little Endian-Format einfallen lassen.
Ich wüßte im Moment auch nicht wie ich andere Freebasic-Anweisungen z.B. "SCREEN 18" portierbar machen sollte?
_________________
Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 24.07.2009, 14:13    Titel: Antworten mit Zitat

das macht freebasic ja für dich. der SCREEN-Aufruf ist ja überall identisch.

Dass du nicht BigEndian in BigEndian konvertieren musst, ist natürlich ein argument... Zunge rausstrecken
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
28398



Anmeldungsdatum: 25.04.2008
Beiträge: 1917

BeitragVerfasst am: 24.07.2009, 18:29    Titel: Antworten mit Zitat

Ich behaupte einfach mal, dass es sowas ähnliches wie BSWAP auch in vielen anderen Architekturen gibt.
Klar wäre das hier ein C Forum hättest du recht, aber falls FBC jemals was anderes als x86 (x86_64) unterstüzten sollte (was überhaupt nicht zu erwarten ist, da die Entwicklung nahezu stagniert ist), ist das auch nur ein #IfDef _X86 o. ä.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Gehe zu Seite 1, 2  Weiter
Seite 1 von 2

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz