| 
				
					|  | Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
 |  
 
	
		| Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |  
		| Autor | Nachricht |  
		| Eternal_pain 
 
  
 Anmeldungsdatum: 08.08.2006
 Beiträge: 1783
 Wohnort: BW/KA
 
 | 
			
				|  Verfasst am: 23.08.2011, 15:15    Titel: ASM (Konform?) Anfängerfragen... |   |  
				| 
 |  
				| habe mal einen kleinen versuch gemacht bisherige funktionen mithilfe von inline ASM zu verbessern, nac einigen Beispielen und dem durchlesen kenn ich zwar hier und da einige Befehle, werde jedoch noch immer nicht ganz schlau daraus... 
 Hier ein Beispiel, das zwar funktioniert, aber zweifel an seiner richtigkeit habe, da ich hier das ecx register nutze das eigentlich für schleifen reseverit oder genutzt ist/wird... ??
 
 Es geht darum einen wert aus einer adresse auszulesen, und diese dann zu dividieren... praktisch ist das die division hier in zwei register geschrieben wird, die einem FIX Variable/Wert und MOD Vaiable/Wert gleichen was mir im ganzem etwas zugespielt hat...
 
 
  	  | Code: |  	  | ASM mov ecx, [PAdr]
 mov eax, [ecx]
 and eax, &hFFFFFF
 mov edx, &h0
 mov ebx, &h08
 div ebx
 mov [CBLByte],eax
 mov [CBLBit],edx
 End ASM
 
 | 
 
 hier benutze ich das einzig frei gebliebene register ecx um auf eine adresse zu zeigen, den 32bit wert in dieser adresse schreibe ich in eax und reduziere den in 24bit (schneide 8bit ab)
 adx muss für die division auf null gesetzt werden, später steht dann der restwert der division dort, ebx enthält den wert mit den es zu teilen gilt
 div teil eax mit ebx
 und übergebe die beiden werte dann zwei weiterverarbeitenden Variablen...
 
 sollte ich hier vielleicht noch etwas beachten?
 _________________
 
  |  |  
		| Nach oben |  |  
		|  |  
		| volta 
 
 
 Anmeldungsdatum: 04.05.2005
 Beiträge: 1876
 Wohnort: D59192
 
 | 
			
				|  Verfasst am: 23.08.2011, 16:22    Titel: |   |  
				| 
 |  
				| Nö, alles Ok. 	  | Zitat: |  	  | sollte ich hier vielleicht noch etwas beachten? | 
 
 Die Register (hier ecx) werden zwar häufig zu speziellen Aufgaben genutzt aber das ist kein MUSS.
 
 das geht auch 	  | Code: |  	  | ASM mov eax, [PAdr] 'Adresse laden
 mov eax, [eax] 'Wert holen
 | 
   
 
 es gibt noch esi, edi !! 	  | Zitat: |  	  | hier benutze ich das einzig frei gebliebene register ecx um auf eine adresse zu zeigen | 
 _________________
 Warnung an Choleriker:
 Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
 Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater.
 |  |  
		| Nach oben |  |  
		|  |  
		| Eternal_pain 
 
  
 Anmeldungsdatum: 08.08.2006
 Beiträge: 1783
 Wohnort: BW/KA
 
 | 
			
				|  Verfasst am: 23.08.2011, 16:35    Titel: |   |  
				| 
 |  
				| Danke Volta   
 5min später war ich auch drauf gekommen das ich statt des ecx, ebx nehmen hätte können, da ich es ja nur 'kurz' zum Wert aus der Adresse holen benötige und anschliessend neu setze...
 
 Jedoch hab ich mich inzwischen für eine glaube kürzere variante entschieden, gar nicht erst auf einen Pointer zuzugreifen und stattdessen den Variablenwert direkt an eax zu übergeben, da ich die adresse in der schleife ja eh immer neu setze, kann ich auch direkt den wert statt der adresse nehmen...
 
 Konnte bei beiden varianten jedenfalls keinen besonderen unterschied in der ausführungsgeschwindigkeit feststellen...
 
 
  	  | Code: |  	  | ASM
 mov ebx, [PAdr]
 mov eax, [ebx]
 and eax, &hFFFFFF
 mov ebx, &h08
 mov edx, &h0
 div ebx
 mov [CBLByte],eax
 mov [CBLBit],edx
 End ASM
 
 | 
 
 
  	  | Code: |  	  | ASM
 mov eax, [IndexColor]
 mov ebx, &h08
 mov edx, &h0
 div ebx
 mov [CBLByte],eax
 mov [CBLBit],edx
 End ASM
 
 | 
 
 das allerdings mov eax, [eax] auch gegangen wäre, darauf wär ich nicht gekommen O.O
 
 Edit:
 esi und edi sind doch für stringoperationen reserviert??
 _________________
 
  |  |  
		| Nach oben |  |  
		|  |  
		| volta 
 
 
 Anmeldungsdatum: 04.05.2005
 Beiträge: 1876
 Wohnort: D59192
 
 | 
			
				|  Verfasst am: 23.08.2011, 16:47    Titel: |   |  
				| 
 |  
				|  	  | Zitat: |  	  | esi und edi sind doch für stringoperationen reserviert?? | 
 wenn du die Register nicht zu "stringoperationen" brauchst, können sie ganz normal benutzt werden.
 _________________
 Warnung an Choleriker:
 Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
 Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater.
 |  |  
		| Nach oben |  |  
		|  |  
		| Eternal_pain 
 
  
 Anmeldungsdatum: 08.08.2006
 Beiträge: 1783
 Wohnort: BW/KA
 
 | 
			
				|  Verfasst am: 24.08.2011, 10:50    Titel: |   |  
				| 
 |  
				| Hier wollte ich versuchshalber einen codeabschnitt weiter in ASM ausbauen und auch wenn ich vermute das es so nicht ganz funktioniert, hänge ich schon bei den befehl 'shl'
 
 Laut der Codetabelle: http://www.jegerlehner.ch/intel/IntelCodeTable.pdf
 sollte das so richtig sein, FB spuckt mir hier dann aber ein:
 
  	  | Zitat: |  	  | Compiler output: E:\FreeBASIC\FBIDETEMP.asm: Assembler messages:
 E:\FreeBASIC\FBIDETEMP.asm:255: Error: suffix or operands invalid for `shl'
 | 
 aus...
 
 
 
  	  | Code: |  	  | ASM mov eax, [IndexColor]
 mov ebx, &h08
 mov edx, &h0
 div ebx
 
 mov ebx, 1
 shl ebx, edx
 mov edx, ebx
 
 mov ebx, [ColorBitList]
 add ebx, eax
 mov eax, ebx
 and eax, edx
 jnz NOSET
 add ebx, eax
 mov eax, [CountColor]
 inc eax
 mov [CountColor], eax
 NOSET:
 
 mov eax, [PAdd]
 add eax, &h04
 mov [PAdd], eax
 End ASM
 | 
 
 http://www.freebasic-portal.de/code-beispiele/grafik-und-fonts/colorcount-farben-zaehlen-161.html
 Das ist der Original FB Code: bei dem ich mich mit ASM versuche auszutoben
  _________________
 
  |  |  
		| Nach oben |  |  
		|  |  
		| volta 
 
 
 Anmeldungsdatum: 04.05.2005
 Beiträge: 1876
 Wohnort: D59192
 
 | 
			
				|  Verfasst am: 24.08.2011, 12:18    Titel: |   |  
				| 
 |  
				| Hi, der Fehler liegt bei SHL. Alle Schiebebefehle erlauben als ersten Parameter ein Register oder eine Speicherstelle.
 Als zweiter Parameter (Anzahl Schiebungen) kann nur eine Konstante (0 - 255) oder das cl-Register angegeben werden.
 Beispiel:
 
  	  | Code: |  	  | 'SHL Test Dim As UInteger x=1
 Asm
 mov eax,[x]
 Shl eax, 5 'Register, Konstante
 mov [x], eax
 End Asm
 ?Hex(x)
 
 x=1
 Asm
 mov eax,[x]
 mov ecx,5
 Shl eax, cl 'Register, cl-Register
 mov [x], eax
 End Asm
 ?Hex(x)
 
 x=1
 Asm Shl dword ptr[x],5 'Speicher, Konstante
 ?Hex(x)
 
 x=1
 Asm
 mov ecx,5
 Shl dword ptr[x],cl 'Speicher, cl-Register
 End Asm
 ?Hex(x)
 
 Sleep
 | 
 _________________
 Warnung an Choleriker:
 Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
 Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater.
 |  |  
		| Nach oben |  |  
		|  |  
		| Eternal_pain 
 
  
 Anmeldungsdatum: 08.08.2006
 Beiträge: 1783
 Wohnort: BW/KA
 
 | 
			
				|  Verfasst am: 24.08.2011, 12:50    Titel: |   |  
				| 
 |  
				| Juhu, ich darf ein spezielles register für eine spezielle aufgabe nutzen   
 Ich habe noch ein Problem damit zu erkennen wann ich auf eine speicherstelle zugreife und wann auf den wert in der speicherstelle...
 und worauf genau sich ein jump bezieht, da ich den jump ja kein
 register übergebe...
 
 Der gesammte abschnitt...
 
  	  | Code: |  	  | ASM mov eax, [IndexColor]
 mov ebx, &h08
 mov edx, &h00
 div ebx
 'eax = fix(IndexColor/ebx (8))
 'edx = (Indexcolor mod ebx (8))
 
 mov ecx, edx
 'ecx = edx (IndexColor mod 8)
 
 mov ebx, &h01
 shl ebx, cl
 'ebx shl ecx|cl - 1 shl ecx???
 
 mov edx, [ColorBitList]
 add edx, [eax] 'Schiebe ich die Speicherstelle,
 'oder schreibe ich in Speicherstelle?
 
 mov eax, edx   'eax soll wert von "neuer"
 'speicherstelle/-bereich enthalten
 
 and eax, ebx   'eax and ebx
 
 jnz NOSET      'jump not zero (was not zero??)
 'soll nur springen wenn eax<>0
 
 'if eax=0 then:
 
 add edx, ebx            'Wert ebx in Speicherstelle edx
 'dazuzählen
 
 mov eax, [CountColor]   'Wert CountColor auf eax
 inc eax                 'eax um 1 erhöhen
 mov [CountColor], eax   'neuen Wert in Variable schreiben
 
 NOSET: 'Sprungmarke
 
 mov eax, [PAdd] 'Wert PAdd auf eax
 add eax, &h04   'eax um 4 erhöhen
 mov [PAdd], eax 'neuen Wert in Variable
 End ASM
 
 | 
 
 
 In diesem Teil:
 
  	  | Code: |  	  | mov edx, [ColorBitList] add edx, [eax] 'Schiebe ich die Speicherstelle,
 'oder schreibe ich in Speicherstelle?
 
 mov eax, edx   'eax soll wert von "neuer"
 'speicherstelle/-bereich enthalten
 
 and eax, ebx   'eax and ebx
 
 jnz NOSET      'jump not zero (was not zero??)
 'soll nur springen wenn eax<>0
 | 
 Hier will ich die Speicheradresse von ColotBitList holen und dann die Speicheradresse 'verschieben' nicht den Wert an dieser Adresse und dort
 dann einen Wert abzufragen um dann quasi ein vergleichbares If/Then auszuführen...
 
 Wie unterscheide ich speicherstelle und speicherinhalt bei so einer aktion?
 _________________
 
  |  |  
		| Nach oben |  |  
		|  |  
		| volta 
 
 
 Anmeldungsdatum: 04.05.2005
 Beiträge: 1876
 Wohnort: D59192
 
 | 
			
				|  Verfasst am: 24.08.2011, 13:38    Titel: |   |  
				| 
 |  
				| ich fange erst mal bei den Flags (siehe deine IntelCodeTabelle 2.Seite unten) an. Viele Instruktionen setzen im Prozessor bestimmte Flag-Bits.
 Eines der wichtigsten ist das Zero-Flag. Alle logischen und Rechenbefehle setzen dieses Bit auf 1 wenn als Ergebnis=0 eintritt.
 Direkt nach dieser Berechnung kann man dieses Flag als Entscheider z.B. für einen Sprung nutzen (IF ZeroFlag = 1 Then Goto Label =  jz Label) (IF ZeroFlag = 0 Then Goto Label =  jnz Label)
 
 So, jetzt wird es etwas unverständlich für mich
   mov edx, [ColorBitList] 'hier wird edx mit dem Wert von ColorBitList geladen
 
 add edx, [eax] 'der Wert aus eax wird als Pointer benutzt. Zu edx wird der Wert addiert der durch den Pointer adressiert wird.
 (Vermutlich ist add edx, dword ptr [eax] nötig, da AS nicht weis auf was für ein Wert (Byte, short, integer) gezeigt wird.)
 Ich hoffe das war deine Frage?
 _________________
 Warnung an Choleriker:
 Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
 Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater.
 |  |  
		| Nach oben |  |  
		|  |  
		| St_W 
 
  
 Anmeldungsdatum: 22.07.2007
 Beiträge: 958
 Wohnort: Austria
 
 | 
			
				|  Verfasst am: 24.08.2011, 13:45    Titel: |   |  
				| 
 |  
				| Ein kleines Beispiel:  	  | Code: |  	  | Dim myStr As String myStr = "ABC"
 
 Dim myStrPtr As ZString Ptr
 myStrPtr = StrPtr(myStr)
 
 Dim Letter_A As Integer
 Dim Letter_B As Integer
 
 Asm
 
 mov eax, [myStrPtr]         'In eax ist der Pointer-Wert (=Adresse)
 
 mov ebx, [eax]               'Auf den Wert bei der Adresse in eax zugreifen, und den Wert in ebx speichern
 mov [Letter_A], ebx
 
 inc eax                           'Adresse selbst ändern
 
 mov ebx, [eax]               'Auf den Wert an der neuen Adresse zugreifen, und den Wert in ebx speichern
 mov [Letter_B], ebx
 
 End Asm
 
 
 Print Chr(Letter_A, Letter_B)
 Sleep
 | 
 
 
 Du verschiebst die Speicherstelle um den Wert, der sich an der Adresse von eax befindet. 	  | Zitat: |  	  | mov edx, [ColorBitList] add edx, [eax] 'Schiebe ich die Speicherstelle,
 'oder schreibe ich in Speicherstelle?
 | 
 
 
 Wenn eax den Wert, und nicht die Adresse erhalten soll, die in edx gespeichert ist, dann musst du auch  schreiben 	  | Zitat: |  	  | mov eax, edx   'eax soll wert von "neuer" 'speicherstelle/-bereich enthalten
 | 
   
 
 Not Zero bedeutet es für den Prozessor, wenn das Zero Flag nicht gesetzt ist. Der Intel-Dokumentation ist zu entnehmen, dass AND das Zero-Flag entsprechend dem Ergebnis setzt, also dürfte das schon so passen. 	  | Zitat: |  	  | jnz NOSET      'jump not zero (was not zero??) 'soll nur springen wenn eax<>0
 | 
 _________________
 Aktuelle FreeBasic Builds, Projekte, Code-Snippets unter http://users.freebasic-portal.de/stw/
 http://www.mv-lacken.at Musikverein Lacken (MV Lacken)
 |  |  
		| Nach oben |  |  
		|  |  
		| Eternal_pain 
 
  
 Anmeldungsdatum: 08.08.2006
 Beiträge: 1783
 Wohnort: BW/KA
 
 | 
			
				|  Verfasst am: 24.08.2011, 15:12    Titel: |   |  
				| 
 |  
				| Vielen Dank euch beiden, das hat mir sehr geholfen, jetzt arbeitet der ASM Abschnitt genauso wie er soll
   
 
  	  | Code: |  	  | Function ColorCount24N (byval Image as any ptr) as UInteger If Image=0 Then Return 0
 
 Dim BufferVersion as UInteger=cast(UInteger ptr,Image)[0]
 Dim BufferBPP     as UInteger=cast(UInteger ptr,Image)[1]
 
 If BufferBPP<4 orelse BufferVersion<>7 Then Return 0
 
 Dim BufferSizeX   as UInteger=cast(UInteger ptr,Image)[2]
 Dim BufferSizeY   as UInteger=cast(UInteger ptr,Image)[3]
 Dim BufferPitch   as UInteger=cast(UInteger ptr,Image)[4]
 
 Dim ColorBitList  as UByte ptr=Callocate(2097152)
 Dim CBLByte       as UInteger
 Dim CBLBit        as UByte
 Dim IndexColor    as UInteger
 Dim CountColor    as UInteger
 Dim PAdrBase      as any ptr
 Dim PAdd          as integer
 PAdrBase = Image+32
 
 For Y as UShort=0 to BufferSizeY-1
 PAdd=0
 For X as UShort=0 to BufferSizeX-1
 
 IndexColor=(cast(uinteger ptr,PAdrBase+PAdd)[0] and &hFFFFFF)
 
 ASM
 mov eax, [IndexColor]
 mov ebx, &h08
 mov edx, &h00
 div ebx
 'eax = fix(IndexColor/ebx (8))
 'edx = (Indexcolor mod ebx (8))
 
 mov ecx, edx
 'ecx = edx (IndexColor mod 8)
 
 mov ebx, &h01
 shl ebx, cl
 'ebx shl ecx|cl - 1 shl ecx???
 
 mov edx, [ColorBitList]
 add edx, eax   'Speicherbereich um wert (eax) verschieben
 
 mov eax, byte ptr [edx]   'byte aus eax holen
 
 and eax, ebx   'eax and ebx
 
 jnz NOSET      'jump not zero
 'if eax=0 then:
 
 add byte ptr [edx], ebx 'Wert ebx in Speicherstelle edx
 'dazuzählen
 
 mov eax, [CountColor]   'Wert CountColor auf eax
 inc eax                 'eax um 1 erhöhen
 mov [CountColor], eax   'neuen Wert in Variable schreiben
 
 NOSET: 'Sprungmarke
 
 mov eax, [PAdd] 'Wert PAdd auf eax
 add eax, &h04   'eax um 4 erhöhen
 mov [PAdd], eax 'neuen Wert in Variable
 End ASM
 
 Next X
 PAdrBase+=BufferPitch
 Next Y
 
 Deallocate (ColorBitList)
 Return CountColor
 End Function
 
 | 
 
 Über Sinn und Unsinn über den ASM teilma ich gar nicht erst bestreiten obwohl es EINIGES in der ausführungsgeschwindigkeit gebracht hat, es sollte mir nur zum üben und verstehen helfen
  _________________
 
  |  |  
		| Nach oben |  |  
		|  |  
		| St_W 
 
  
 Anmeldungsdatum: 22.07.2007
 Beiträge: 958
 Wohnort: Austria
 
 | 
			
				|  Verfasst am: 24.08.2011, 15:52    Titel: |   |  
				| 
 |  
				| Manchmal bringt ASM Code in FB doch noch merkbare Geschwindigkeitsvorteile, da ja bekanntermaßen FB nicht wirklich viel optimiert. 
 Wenn man zu faul ist ASM Code selber zu schreiben, so wie ich es manchmal bin, kann man auch den gcc die Arbeit erledigen lassen und dessen ASM output in FB als ASM einbinden - hab ich schon hier und da gemacht.
 _________________
 Aktuelle FreeBasic Builds, Projekte, Code-Snippets unter http://users.freebasic-portal.de/stw/
 http://www.mv-lacken.at Musikverein Lacken (MV Lacken)
 |  |  
		| Nach oben |  |  
		|  |  
		| Eternal_pain 
 
  
 Anmeldungsdatum: 08.08.2006
 Beiträge: 1783
 Wohnort: BW/KA
 
 | 
			
				|  Verfasst am: 24.08.2011, 16:44    Titel: |   |  
				| 
 |  
				| Es bringt immerhin gute 50%, dafür lohnt ein wenig aufwandt schon   
 Allerdings habe ich noch einen fehler entdeckt:
 und zwar werden mir bei
 
  	  | Code: |  	  | mov eax, byte ptr [edx] | 
 und
 
  	  | Code: |  	  | add byte ptr [edx], ebx | 
 Warnungen vom compiler gegeben,
 lasse ich byte ptr weg sind zwar die Warnungen weg,
 wenn ich aber nicht falsch liege, liesst er dann 4byte lang, wegen der 32bit register?
 Wenn dem so ist würde sich alles ja um 3byte nach recht verschieben und in ausnahmefällen ausserhalb des reservierten bereichs schreiben...
 jetzt könnte ich das ganze so stehen lassen und einfach 3byte mehr speicher reservieren, aber eigentlich sollte das nicht sinn der aufgabe sein.
 ich möchte ja in den adressbereich jeweils nur 1byte auslesen bzw schreiben...
 _________________
 
  |  |  
		| Nach oben |  |  
		|  |  
		| volta 
 
 
 Anmeldungsdatum: 04.05.2005
 Beiträge: 1876
 Wohnort: D59192
 
 | 
			
				|  Verfasst am: 24.08.2011, 18:02    Titel: |   |  
				| 
 |  
				| ja richtig, wenn du nur ein Byte laden oder speichern willst mußt du auch ein ByteRegister angeben:
 
 
  	  | Code: |  	  | mov al, byte ptr [edx] | 
 und
 
  	  | Code: |  	  | add byte ptr [edx], bl | 
 _________________
 Warnung an Choleriker:
 Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
 Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater.
 |  |  
		| Nach oben |  |  
		|  |  
		| Eternal_pain 
 
  
 Anmeldungsdatum: 08.08.2006
 Beiträge: 1783
 Wohnort: BW/KA
 
 | 
			
				|  Verfasst am: 24.08.2011, 23:36    Titel: |   |  
				| 
 |  
				| Gut zu wissen, so macht es keine Schwierigkeiten mehr. Dachte allerdings das es bei übergabe und zuweisung keinen
 wirklichen unterschied macht aufgrund dieses
 Beispiels, aber leuchtet letztlich ein....
 
 
  	  | Code: |  	  | 'Beispiel:Register Bitbelgung (eax) '|<-----------eax----------->|
 '|.............|<----ax----->|
 '|.............|<-ah->|<-al->|
 '|------+------+------+------|
 '| Bits | Bits | Bits | Bits |
 '|31- 24|23- 16|15 - 8| 7 - 0|
 
 Dim ASMDWord as UInteger
 Dim ASMWord  as UShort
 Dim ASMhWord as UByte
 Dim ASMlWord as UByte
 
 Asm
 mov eax,&hF1F2F3F4     'Teile eax(32bit register) einen Wert zu
 'Übergeben von Variable (Add, dazuaddieren bzw mov, übergeben)
 'sollte keinen unterschied in diesem Beispiel ausmachen??
 mov [ASMDWord], eax    'Übergebe wert aus eax an Variable
 mov [ASMWord], ax      'Übergebe loword aus eax an variable
 mov [ASMhWord], ah     'übergebe hibyte aus eax/ax an variable
 mov [ASMlWord], al     'übergebe lobyte aud eax/ax an variable
 End ASM
 
 ?hex(ASMDWord)
 ?hex(ASMWord)
 ?hex(ASMhWord)
 ?hex(ASMlWord)
 | 
 
 Jedenfalls, bin ich schwer begeistert was so noch alles rauszuholen ist
   
   
 Die ergebnisse können sich schon sehen lassen:
 
 
  	  | Code: |  	  | Function ColorCount (byval Image as any ptr) as UInteger If Image=0 Then Return 0
 
 Dim BufferVersion as UInteger=Peek(UInteger,Image)
 
 If BufferVersion<>7 Then Return 0
 
 Dim BufferBPP     as UInteger=Peek(UInteger,Image+4)
 Dim BufferSizeX   as UInteger=Peek(UInteger,Image+8)
 Dim BufferSizeY   as UInteger=Peek(UInteger,Image+12)
 
 Dim BufferPitch   as UInteger=Peek(UInteger,Image+16)
 
 Dim ColorBitList as UByte ptr=Callocate(2097152)
 
 Dim CBLByte as UInteger
 Dim CBLBit  as UByte
 
 Dim IndexColor as UInteger
 Dim CountColor as UInteger
 
 For Y as UInteger=0 to BufferSizeY-1
 For X as UInteger=0 to BufferSizeX-1
 
 Select Case as Const BufferBPP
 Case 1
 IndexColor=Peek (Ubyte ,Image+32+(X*BufferBPP)+(Y*BufferPitch))
 Case 2
 IndexColor=Peek (UShort ,Image+32+(X*BufferBPP)+(Y*BufferPitch))
 Case Else
 IndexColor=Peek (UInteger ,Image+32+(X*BufferBPP)+(Y*BufferPitch)) and &h00FFFFFF
 End Select
 
 CBLByte = Fix(IndexColor/8)
 CBLBit  = (IndexColor mod 8)
 
 If Bit(ColorBitList[CBLByte],CBLBit)=0 Then
 CountColor+=1
 ColorBitList[CBLByte]+=(1 SHL CBLBit)
 End If
 
 Next X
 Next Y
 
 Deallocate (ColorBitList)
 
 Return CountColor
 End Function
 
 
 Function ColorCount24 (byval Image as any ptr) as UInteger
 If Image=0 Then Return 0
 
 Dim BufferVersion as UInteger=cast(UInteger ptr,Image)[0]
 Dim BufferBPP     as UInteger=cast(UInteger ptr,Image)[1]
 
 If BufferBPP<4 orelse BufferVersion<>7 Then Return 0
 
 Dim BufferSizeX   as UInteger=cast(UInteger ptr,Image)[2]
 Dim BufferSizeY   as UInteger=cast(UInteger ptr,Image)[3]
 Dim BufferPitch   as UInteger=cast(UInteger ptr,Image)[4]
 
 Dim ColorBitList  as UByte ptr=Callocate(2097152)
 Dim CBLByte       as UInteger
 Dim CBLBit        as UByte
 Dim IndexColor    as UInteger
 Dim CountColor    as UInteger
 Dim PAdrBase      as any ptr
 Dim PAdd          as integer
 PAdrBase = Image+32
 
 For Y as UInteger=0 to BufferSizeY-1
 PAdd=0
 For X as UInteger=0 to BufferSizeX-1
 
 IndexColor=(cast(uinteger ptr,PAdrBase+PAdd)[0] and &hFFFFFF)
 
 ASM
 mov eax, [IndexColor]
 mov ebx, &h08
 mov edx, &h0
 div ebx
 mov [CBLByte],eax
 mov [CBLBit],edx
 End ASM
 
 If Bit(ColorBitList[CBLByte],CBLBit)=0 Then
 CountColor+=1
 ColorBitList[CBLByte]+=(1 SHL CBLBit)
 End If
 
 PAdd+=4
 Next X
 PAdrBase+=BufferPitch
 Next Y
 
 Deallocate (ColorBitList)
 Return CountColor
 End Function
 
 Function ColorCountASM (byval Image as any ptr) as UInteger
 If Image=0 Then Return 0
 
 Dim BufferVersion as UInteger=cast(UInteger ptr,Image)[0]
 Dim BufferBPP     as UInteger=cast(UInteger ptr,Image)[1]
 
 If BufferBPP<4 orelse BufferVersion<>7 Then Return 0
 
 Dim BufferSizeX   as UInteger=cast(UInteger ptr,Image)[2]
 Dim BufferSizeY   as UInteger=cast(UInteger ptr,Image)[3]
 Dim BufferPitch   as UInteger=cast(UInteger ptr,Image)[4]
 
 Dim ColorBitList  as UByte ptr=Callocate(2097152)
 Dim CBLByte       as UInteger
 Dim CBLBit        as UByte
 Dim IndexColor    as UInteger
 Dim CountColor    as UInteger
 Dim PAdrBase      as any ptr
 Dim PAdd          as integer
 PAdrBase = Image+32
 
 ASM
 mov edi, [BufferSizeY]
 SCHLEIFEY:
 mov eax, 0
 mov [PAdd], eax
 
 mov esi, [BufferSizeX]
 SCHLEIFEX:
 mov ebx, [PAdrBase]
 add ebx, [PAdd]
 mov ebx, [ebx]
 and ebx, &hFFFFFF
 
 mov eax, ebx
 mov ebx, &h08
 mov edx, &h00
 div ebx
 
 mov ecx, edx
 
 mov ebx, &h01
 shl ebx, cl
 
 mov edx, [ColorBitList]
 add edx, eax
 
 mov al, byte ptr [edx]
 and al, bl
 jnz NOSET
 
 add byte ptr [edx], bl
 mov eax, [CountColor]
 inc eax
 mov [CountColor], eax
 
 NOSET:
 
 mov eax, [PAdd]
 add eax, &h04
 mov [PAdd], eax
 
 dec esi
 jnz SCHLEIFEX
 
 mov eax, [PAdrBase]
 add eax, [BufferPitch]
 mov [PAdrBase], eax
 
 dec edi
 jnz SCHLEIFEY
 End ASM
 
 Deallocate (ColorBitList)
 Return CountColor
 End Function
 
 
 Screen 19,32
 Dim test as any ptr
 test=ImageCreate (800,600)
 Bload "Test.bmp",test
 put (0,0),test,pset
 
 Dim CCTimer  as Double
 Dim CCResult as Double
 Dim CC       as UInteger
 'ColorCount24
 sleep 5
 CCTimer=Timer
 CC=ColorCount(Test)
 CCResult=(Timer-CCTimer)
 
 Print "ColorCount    Count: ";CC;
 Print USING " Time: #.##########";CCResult
 
 sleep 5
 CCTimer=Timer
 CC=ColorCount24(Test)
 CCResult=(Timer-CCTimer)
 
 Print "ColorCount24  Count: ";CC;
 Print USING " Time: #.##########";CCResult
 
 sleep 5
 CCTimer=Timer
 CC=ColorCountASM(Test)
 CCResult=(Timer-CCTimer)
 
 Print "ColorCountASM Count: ";CC;
 Print USING " Time: #.##########";CCResult
 
 sleep
 | 
 _________________
 
  |  |  
		| Nach oben |  |  
		|  |  
		|  |  
  
	| 
 
 | 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.
 
 |  |