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:

ASM (Konform?) Anfängerfragen...

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Profi-Forum
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Eternal_pain



Anmeldungsdatum: 08.08.2006
Beiträge: 1783
Wohnort: BW/KA

BeitragVerfasst am: 23.08.2011, 15:15    Titel: ASM (Konform?) Anfängerfragen... Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen MSN Messenger
volta



Anmeldungsdatum: 04.05.2005
Beiträge: 1875
Wohnort: D59192

BeitragVerfasst am: 23.08.2011, 16:22    Titel: Antworten mit Zitat

Zitat:
sollte ich hier vielleicht noch etwas beachten?
Nö, alles Ok.

Die Register (hier ecx) werden zwar häufig zu speziellen Aufgaben genutzt aber das ist kein MUSS.
Code:
ASM
            mov eax, [PAdr] 'Adresse laden
            mov eax, [eax] 'Wert holen
das geht auch grinsen

Zitat:
hier benutze ich das einzig frei gebliebene register ecx um auf eine adresse zu zeigen
es gibt noch esi, edi !!
_________________
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
Eternal_pain



Anmeldungsdatum: 08.08.2006
Beiträge: 1783
Wohnort: BW/KA

BeitragVerfasst am: 23.08.2011, 16:35    Titel: Antworten mit Zitat

Danke Volta lächeln

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen MSN Messenger
volta



Anmeldungsdatum: 04.05.2005
Beiträge: 1875
Wohnort: D59192

BeitragVerfasst am: 23.08.2011, 16:47    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Eternal_pain



Anmeldungsdatum: 08.08.2006
Beiträge: 1783
Wohnort: BW/KA

BeitragVerfasst am: 24.08.2011, 10:50    Titel: Antworten mit Zitat

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 zwinkern
_________________
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen MSN Messenger
volta



Anmeldungsdatum: 04.05.2005
Beiträge: 1875
Wohnort: D59192

BeitragVerfasst am: 24.08.2011, 12:18    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Eternal_pain



Anmeldungsdatum: 08.08.2006
Beiträge: 1783
Wohnort: BW/KA

BeitragVerfasst am: 24.08.2011, 12:50    Titel: Antworten mit Zitat

Juhu, ich darf ein spezielles register für eine spezielle aufgabe nutzen grinsen

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen MSN Messenger
volta



Anmeldungsdatum: 04.05.2005
Beiträge: 1875
Wohnort: D59192

BeitragVerfasst am: 24.08.2011, 13:38    Titel: Antworten mit Zitat

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 durchgeknallt
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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
St_W



Anmeldungsdatum: 22.07.2007
Beiträge: 955
Wohnort: Austria

BeitragVerfasst am: 24.08.2011, 13:45    Titel: Antworten mit Zitat

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


Zitat:
mov edx, [ColorBitList]
add edx, [eax] 'Schiebe ich die Speicherstelle,
'oder schreibe ich in Speicherstelle?
Du verschiebst die Speicherstelle um den Wert, der sich an der Adresse von eax befindet.

Zitat:
mov eax, edx 'eax soll wert von "neuer"
'speicherstelle/-bereich enthalten
Wenn eax den Wert, und nicht die Adresse erhalten soll, die in edx gespeichert ist, dann musst du auch
Code:
mov eax, [edx]
schreiben zwinkern

Zitat:
jnz NOSET 'jump not zero (was not zero??)
'soll nur springen wenn eax<>0
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.
_________________
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
Eternal_pain



Anmeldungsdatum: 08.08.2006
Beiträge: 1783
Wohnort: BW/KA

BeitragVerfasst am: 24.08.2011, 15:12    Titel: Antworten mit Zitat

Vielen Dank euch beiden, das hat mir sehr geholfen,
jetzt arbeitet der ASM Abschnitt genauso wie er soll lächeln

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 lächeln
_________________
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen MSN Messenger
St_W



Anmeldungsdatum: 22.07.2007
Beiträge: 955
Wohnort: Austria

BeitragVerfasst am: 24.08.2011, 15:52    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Eternal_pain



Anmeldungsdatum: 08.08.2006
Beiträge: 1783
Wohnort: BW/KA

BeitragVerfasst am: 24.08.2011, 16:44    Titel: Antworten mit Zitat

Es bringt immerhin gute 50%, dafür lohnt ein wenig aufwandt schon lächeln

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen MSN Messenger
volta



Anmeldungsdatum: 04.05.2005
Beiträge: 1875
Wohnort: D59192

BeitragVerfasst am: 24.08.2011, 18:02    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Eternal_pain



Anmeldungsdatum: 08.08.2006
Beiträge: 1783
Wohnort: BW/KA

BeitragVerfasst am: 24.08.2011, 23:36    Titel: Antworten mit Zitat

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 lächeln


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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen MSN Messenger
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Profi-Forum Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
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