Bits auslesen

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Leonhard
Beiträge: 602
Registriert: 01.03.2006 21:25

Bits auslesen

Beitrag von Leonhard »

Hi,

Ich von einer CPU die Versionsinformationen bekommen. Ich diese jetz auch mit diesem Code bekommen:

Code: Alles auswählen

Define VersionInfo.l

!MOV eax, 1
!CPUID

!MOV [v_VersionInfo], eax

Debug Bin(VersionInfo)
Die Verionsinformationen sind folgendermaßen aufgebaut:
Versionsinfo-Bits:
0-3: Stepping ID
4-7: Modell
8-11: Familie
12-13: Prozessortyp
Wie kann ich jetzt die Bits auslesen bzw. in mehrere Variablen unterteilen? Ich bekomm das selbst mit BitShift nicht so richtig hin.
Benutzeravatar
String
Beiträge: 69
Registriert: 17.05.2007 16:22

Beitrag von String »

Suchst so was ?

Code: Alles auswählen

Define VersionInfo.l
!MOV eax, 1
!CPUID
!MOV [v_VersionInfo], eax

info.s = Bin(VersionInfo)
Debug info
For a = 1 To Len(info)
  Debug Mid(info, a, 1) 
Next a
PB v4.**
Benutzeravatar
Scarabol
Beiträge: 1427
Registriert: 30.11.2005 21:00

Beitrag von Scarabol »

Hallo,

ich versteh nicht warum du auf Bitshift oder wie es heißt zurückgreifen willst, wenn du es auch einfach mit Mid() machen kannst. Den Binary String hast du ja schon musst ihn nurnoch zerlegen und zurückkonvertieren.

Code: Alles auswählen

Define VersionInfo.l

!MOV eax, 1
!CPUID

!MOV [v_VersionInfo], eax

String.s = Bin(VersionInfo)

ID.s = Mid(String, 0, 3)
Modell.s = Mid(String, 3, 3)
; usw
Debug String
Gruß
Scarabol
Abgeschlossen Projekte:
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea

PB-V: 4
WinXP
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

ich glaubs ja nich...

da verschieb ich das nach anfänger, weils so ne einfache frage is,
und dann werden hier strings angeschleppt... *koppschüttel*

Code: Alles auswählen

;0-3: Stepping ID
;4-7: Modell
;8-11: Familie
;12-13: Prozessortyp 

StepID  = (VersionInfo & $000F)
Model   = (VersionInfo & $00F0) >> 4
Family  = (VersionInfo & $0F00) >> 8
CPUType = (VersionInfo & $F000) >> 12
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Leonhard
Beiträge: 602
Registriert: 01.03.2006 21:25

Beitrag von Leonhard »

Dank, das was, was ich brauche! :allright:

Das mit Strings bringt mir nichts, da ich bestimmte Bits wieder auslesen mögchte und weiter verwenden. Bei BitShift (Verschieben) solltet ihr mal in den Operatoren nachlesen. Das ist der Operator '>>' oder auch '<<'!

Wie kann man daraus ein Macro machen?
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

> Wie kann man daraus ein Macro machen?

hm.. dann überleg doch mal.

ein macro stellt praktisch ein code-stück dar, dass so wie es ist eingesetzt wird an der stelle, wo sein "aufruf" steht.
dafür musst du zwei grundlegende dinge beachten:
1. der eingangswert kann auch ein ausdruck sein, also solltest du ihn einzeln in klammern setzen.
2. soll der ergebnisausdruck zugewiesen werden oder in einer rechnung stehen können,
darf das gesamte macro keine zeilenumbrüche enthalten, und es sollte komplett in klammern stehen.

in diesem fall ist das wirklich nicht schwer. probiers mal.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Leonhard
Beiträge: 602
Registriert: 01.03.2006 21:25

Beitrag von Leonhard »

Stimmt das so? Oder kann man da nocht was Optimieren?

Code: Alles auswählen

Macro GetBytes(Value, Size, Start)
  ( ((Value) & ((Size)*(Size)-1) << (Start)) >> (Start) )
EndMacro

Debug Bin(GetBytes(%1111<<0, 4, 0))
Debug Bin(GetBytes(%1001<<4, 2, 4))
Debug Bin(GetBytes(%1111<<6, 4, 6))
Debug Bin(GetBytes(%0110<<2, 2, 2))
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

achso... du meinst ein einziges allgemeingültiges Macro...

das is natürlich etwas komplexer.

Code: Alles auswählen

Macro GetBits(Value, Size, Start)
  ( ( (Value) >> (Start) ) & Int(Pow(2,Size)-1) )
EndMacro 

test.l = %1110001110001110

Debug Bin(GetBits(test, 5, 5)) ; 11100
Debug Bin(GetBits(test, 4, 7)) ; 0111
Debug Bin(GetBits(test, 7, 3)) ; 1110001
Debug Bin(GetBits(test, 6, 4)) ; 111000
Debug Bin(GetBits(test, 8, 8)) ; 11100011
ich dachte jetzt an vier einzelne macros, die dir das Word in die vier Nibbles zerschneiden:

Code: Alles auswählen

Macro LoNib( Value )
  ( ( Value ) & $000F )
EndMacro

Macro LoMiNib( Value )
  ( ( ( Value ) & $00F0 ) >> 4 )
EndMacro

Macro HiMiNib( Value )
  ( ( ( Value ) & $0F00 ) >> 8 )
EndMacro

Macro HiNib( Value )
  ( ( ( Value ) & $F000 ) >> 12 )
EndMacro


StepID  = LoNib(VersionInfo)
Model   = LoMiNib(VersionInfo)
Family  = HiMiNib(VersionInfo)
CPUType = HiNib(VersionInfo)
es ist dir vielleicht aufgefallen, dass VersionInfo aus ganzen Nibbles zusammengesetzt ist,
und nicht in krumme bit-anzahlen (hier mal 3 da mal 7) zerfällt.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Leonhard
Beiträge: 602
Registriert: 01.03.2006 21:25

Beitrag von Leonhard »

Kaeru Gaman hat geschrieben:es ist dir vielleicht aufgefallen, dass VersionInfo aus ganzen Nibbles zusammengesetzt ist,
und nicht in krumme bit-anzahlen (hier mal 3 da mal 7) zerfällt.
Das ist mir aufgefallen. Aber ich benötige, wie hier auch andere einträge wie z.B. 0-7, 8-15, ...

Stimmt mein Macro überhaupt?
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

> Aber ich benötige, wie hier auch andere einträge wie z.B. 0-7, 8-15,
was wiederum ganze bytes sind, dazu wären dann Macros wie LoByte / HiByte nützlich...

natürlich ist es praktisch, ein einziges Macro zu haben,
aber das wird dann aufgrund der allgemeingültigkeit etwas langsamer als mehrere einzelne.


> Stimmt mein Macro überhaupt?

nicht ganz, hier hast du nen fehler:
((Size)*(Size)-1) << (Start))

x^2 -1 ist nicht dasselbe wie 2^x -1

...und eben grad geht mir auf, dass man den Pow-Aufruf bei mir garnicht bräuchte.
ein 2^x kann man auch mit nem bitshift hinbekommen.

Code: Alles auswählen

Macro GetBits(Value, Size, Start)
  ( ( (Value) >> (Start) ) & ((1 << (Size))-1) )
EndMacro 
das dürfte dann noch etwas performanter sein....

natürlich bekommt man ne fehlermeldung, wenn einer der werte nicht integer ist,
und es kommt müll raus, wenn Size oder Start zu groß sind.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Antworten