![]() |
Elemente in Mengen mit ASM zählen
Hallo,
ich würde gerne die Anzahl der Elemente in einer Menge zählen, in der Art:
Delphi-Quellcode:
Da ich in Delphi keine Funktion gefunden habe, habe ich es mal mit dem Inline-Assembler versucht. Der Tag an dem ich das letzte mal etwas mit Assembler gemacht habe, ist jedoch schon etwas her...
type
TMenge = set of 0.255 var Menge : TMenge; begin Menge := [3, 5, 110]; writeln(Length(Menge)); // gibt 3 aus end; Der Anfang war ja aber noch recht leicht. Wie zu erwarten, steht im Speicher für jedes Element der Menge ein Bit (1 = "Element drin", 0 = "Element nicht drin"). Was mir noch aufgefallen ist: Für bis zu 4 Byte/32 Bit (dementsprechend bis zu 32 Elementen) wird eine Menge als Werte-, ab 33 Elementen als Referenzparameter übergeben. Also übergebe ich lieber gleich die Adresse der Menge als Pointer an meine Assembler-Funktion und lade dann aus dem Speicher... Jetzt das Problem: Um möglichst wenig Redundanz zu erhalten, werden natürlich nicht immer gleich 32 Byte für jeden beliebigen Mengen-Typ reserviert, sondern nur so viele, wie gebraucht werden (in diesen Schritten: 1, 2, 4, 8, 16 oder 32 Bytes). Woher weiß ich aber, wie lang mein Mengentyp ist, wieviele Bytes ich also aus dem Speicher in die Register laden muss, um dort dann die Bits auf 1 auszählen zu können? Hier der Anfang:
Delphi-Quellcode:
Danke und Gruß,
function Length(PNT : Pointer) : Byte;
asm MOV EAX,[EAX] // Bits auszählen, evtl. weitere Speicherbereiche laden,... RET end; Lucas |
Re: Elemente in Mengen mit ASM zählen
Ich wüsste was viel eleganteres:
Delphi-Quellcode:
type
TMenge = set of 0..255; function Length(victim: TMenge): Integer; var i: Integer; begin Result := 0; for i := 0 to 255 do if i in victim then Inc(Result); end; |
Re: Elemente in Mengen mit ASM zählen
Ich würd das in etwa so machen:
Delphi-Quellcode:
function countElements(ASet: TMySet): Integer;
asm mov eax, [eax] mov ecx, 0 @loop: mov edx, eax and edx, 1 add ecx, edx shr eax, 1 jnz @loop mov eax, ecx end; |
Re: Elemente in Mengen mit ASM zählen
Wie macht man es bei einem 'Set Of TFoobar'? Klappt das dann?
Ich würde, weil ich selten mit Mengen arbeite, mir den 5-Zeiler von Dax an die jeweilige Menge anpassen und als Template ablegen.
Delphi-Quellcode:
Und '|Type|' wird im Template durch die Basistype der Menge (TFoobar, Byte etc.) ersetzt.
Function SetOf|Type|Length (aSet : T|Type|Set) : Byte;
Var i : |Type|; Begin Result := 0; For i:= Low (|Type|) To High (|Type|) Do If i in aSet Then Inc (Result) End; @3_of_8: Ich kenn mich mit Intel-Assembler gar nicht aus, aber stimmt es, das Du einfach so lange die bits zählst, bis das Byte leer ist? Dann wird Deine Funktion bei einem TByteset mit den Elementen [255,0] nicht richtig funktionieren. |
Re: Elemente in Mengen mit ASM zählen
Warum nicht?
Ich addiere zum Zähler 1 dazu, wenn das niedrigste Bit gesetzt ist und shifte dann nach rechts. |
Re: Elemente in Mengen mit ASM zählen
Na, ich dachte Die Menge [0,255] wird doch als 8 bytes [70,00,00,00,00,00,00,01] dargestellt. die Bytes 2-7 sind eh null.
Bis wohin wird denn da geshiftet? Ich sags nochmal: Ich bin ASM-Depp (auch ein passender Nick für mich :stupid: ) und lasse mich von Dir gerne aufklären.. |
Re: Elemente in Mengen mit ASM zählen
Du brauchst nicht unbedingt Assemblercode, um Bits schnell zu zählen:
![]() |
Re: Elemente in Mengen mit ASM zählen
:thumb:
|
Re: Elemente in Mengen mit ASM zählen
In dem Fall würde es dennoch funktionieren.
1000 0001 => Counter wird inkrementiert 0100 0000 => Counter bleibt gleich 0010 0000 => Counter bleibt gleich 0001 0000 => Counter bleibt gleich 0000 1000 => Counter bleibt gleich 0000 0100 => Counter bleibt gleich 0000 0010 => Counter bleibt gleich 0000 0001 => Counter wird inkrementiert 0000 0000 => Schleife beendet |
Re: Elemente in Mengen mit ASM zählen
3_of_8: Es sind 8 Bytes, nicht eins.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:25 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz