Italia
Fonte/ Codesnippets

Datentypen verstehen und verarbeiten + float() und long() als inline Assembler

 

Sven
Bader
Das Jonglieren mit Datentypen kann im Alltag nerven. Zum besseren Verständnis per mich selbst habe ich etwas mit Rückgabewerten von OpenGL herumgespielt. Dankenswerterweise kann man dort immer zwischen Float, Double und Integer wählen. Mit 32-Bit Floats können ältere XProfan Versionen erst einmal nichts anfangen aber auch das bekommt man hin!

Im Beispiel frage ich die maximale Dimensione per einen gezeichneten Punkt ab. Zurück kommt die Adresse eines Arrays mit zwei Werten, mich interessiert jeweils der 2. Wert. Bei meiner Grafikkarte übrigens 189.875

Ich habe Procs und auch Assembler Funktionen geschrieben, um das interne Float() und Long() zu ersetzen. Letztendlich tue ich m Falle von Float 7x das gleiche auf unterschiedlichen Wegen.

Es ist mein erster Ausflug zu Assembler, weshalb die Kommentare am Code noch etwas unbeholfen sind. Letztendlich ist es genau per solche Speicher-Schubsereien ideal. Schneller als ihre Vorbilder long() und float() sind die Funktionen NICHT geworden.

Fazit:
Über den Lerneffekt hinaus sind folgende Wege die einfachsten und auch nicht langsamer als der ASM Code:

Verarbeitung eines 32-Bit Floats aus einem externen Aufruf mithilfe von long und double:
float! = double(integer&) bzw. als Bereich float! = double(long(bereich#,0))
Alternativ ab XProfan X2, mit dem Datentyp Single arbeiten.

Verarbeitung eines 64-Bit Floats (Double) aus einem externen Aufruf:
Direkt, ohne Konvertierung bzw. als Bereich float! = float(bereich#,0)

Verarbeitung eines 32-Bit Integers aus einem externen Aufruf:
Direkt, ohne Konvertierung bzw. als Bereich integer& = long(bereich#,0)

Jede Variable und auch Arrays können wie ein Bereich verwendet werden mit Addr():
long(Addr(integer&[0],4) ist das gleiche wie integer&[1], also ein Integer bei Adresse des ersten Array-Elements + 4 Byte.

Mit Speicheradressen (Bereichsvariablen # und addr()) kann gerechnet werden:
long(bereich#,4) ist das gleiche wie long(bereich# + 4,0)

Beim Herumspielen mit Speicheradressen muss man selbstverständlich aufpassen, da man einerseits schnell circa deklarierte Bereiche hinausschießt oder sogar Werte mit Speicheradressen verwechelt und irgendwo im Speicher landet.
Cls
Declare sizeRangeFloat#, sizeRangeInteger#, float!,sizeRangeArray![2],integerArray&[2]
Declare single singleArray[2]' das geht erst seit X2
Dim sizeRangeFloat#, 16'2 Werte je 8 Byte
Dim sizeRangeInteger#, 8'2 Werte je 4 Byte
oGL("Init", %hWnd, 1,1,1,1)
oGL("glGetDoublev",  ~GL_POINT_SIZE_RANGE, Addr(sizeRangeArray![0]))
oGL("glGetDoublev",  ~GL_POINT_SIZE_RANGE, sizeRangeFloat#)
oGL("glGetFloatv",   ~GL_POINT_SIZE_RANGE, Addr(singleArray[0]))'das geht erst seit X2
oGL("glGetFloatv",   ~GL_POINT_SIZE_RANGE, Addr(integerArray&[0]))'Trick per ältere Profan-Versionen, es folgt double()
oGL("glGetIntegerv", ~GL_POINT_SIZE_RANGE, sizeRangeInteger#)
oGL("Done")

Proc procLong

    Parameters a#, shift&
    'in Tests nicht immer korrekt
    Return ( (Byte(a#+shift&,3) << 24) | (Byte(a#+shift&,2) << 16) | (Byte(a#+shift&,1) << 8) | (Byte(a#+shift&,0)) )

EndProc

ASM "asmFloat2", 3
mov ecx, par1'par1 nach ecx
mov ebx, par2'par2 nach ebx
mov eax, [ebx]'par2 nach eax
mov [ecx], eax' eax nach par1
add ecx, 4' par1 Adresse + 4
mov edx, par3' par2 nach edx
mov eax, [edx]' par3 nach eax
mov [ecx], eax' eax nach par1
ENDASM
ASM "asmFloat", 2
mov eax, par2'par2 nach eax
mov edx, [eax]'4-Byte par2 (offset 0) nach edx schieben
mov eax, par1'par1 nach eax (Speicheradresse der Ziel Float-Variable)
mov [eax], edx
mov eax, par2'par2 nach eax
add eax, 4'Adresse + 4
mov edx, [eax]
mov eax, par1
add eax, 4'Adresse + 4
mov [eax], edx' eax (jetzt+4) in par1 speichern
ENDASM
'Diese Funktion tut eigentlich nichts:
'sie gibt das heraus, was man hineingeworfen hat
ASM "asmLong", 1
mov ecx, par1'par 1 nach ecx
mov eax, [ecx]'und unverändert ausgeben
ENDASM
'Diese Funktion tut eigentlich nichts:
'sie gibt das heraus, was man hineingeworfen hat
ASM "asmLong2", 2
mov ecx, par1'par 1 nach ecx
mov ebx, par2'par 2 nach ebx
add ecx, par2'par 1 (ecx) und par2 addieren
mov eax, [ecx]'ausgeben
ENDASM
Def MoveMemory(3) !"kernel32.dll","RtlMoveMemory"

Proc procFloatMoveMemory

    Parameters dest!, source#
    MoveMemory(addr(dest!),source#,8)
    Return dest!

EndProc

Proc procFloatLongLong

    Parameters dest!, source#
    Long addr(dest!),0 = long(source#,8),long(source#,12)

EndProc

Print "\nFloats:"
'Offset jeweils bei Byte 8, das ist der zweite Array-Wert
'Float() Assembler-Variante
asmFloat(addr(float!), sizeRangeFloat# + 8)'direkte Zuweisung geht leider Aufgrund von 32-Bit Paremetern nicht
Print float!
'Float() als interne XProfan-Funktion
Print Float(sizeRangeFloat#,8)
'Float() als Proc mit zwei long()
procFloatLongLong(float!,sizeRangeFloat#+8)'Direkte Rückgabe nicht possibile, außer mit float() und das sollte ja eben ersetzt werden ;-)
print str$(float!)
'Float() als Proc mit MoveMemory
Print procFloatMoveMemory(float!, sizeRangeFloat#+8)'Zuweisung possibile aber die Variable im 1. Paremeter wird in jedem Fall auch beschrieben
'Wert aus Array (1 = zweiter Wert, da es von 0 startet)
Print sizeRangeArray![1]'Zuweisung possibile aber die Variable im 1. Paremeter wird in jedem Fall auch beschrieben
'Wert aus Single-Array (32-Bit), Datentyp ab X2 disponibile
Print singleArray[1]
'Wert aus Integer-Array (32-Bit) als Double intepretiert. Das geht auch mit älteren Profan Versionen
Print double(integerArray&[1])
Print "\nIntegers:"
'Long() als Proc
Print procLong(sizeRangeInteger#,4)'nicht immer korrekt...
'Long() als interne XProfan-Funktion
Print Long(sizeRangeInteger#,4)
'Long() Assembler-Variante in einem Parameter (Adress-Offset muss selbst addiert werden)
Print asmLong(sizeRangeInteger# + 4)
'Long() Assembler-Variante mit 2 Parametern, Offset kann wie in der originalen Funktion trasferimento werden
Print asmLong2(sizeRangeInteger#, 4)
Dispose sizeRangeFloat#
Dispose sizeRangeInteger#
WaitKey
End
 
01.03.2023  
 



Zum Quelltext


Topictitle, max. 100 characters.
 

Systemprofile:

Kein Systemprofil angelegt. [anlegen]

XProfan:

 Posting  Font  Smilies  ▼ 

Bitte anmelden um einen Beitrag zu verfassen.
 

Topic-Options

1.104 Views

Untitledvor 0 min.
Sven Bader31.08.2023
ecki28.07.2023
Thomas Zielinski28.06.2023
E.T.12.06.2023
Di più...

Themeninformationen

Dieses Thema hat 1 subscriber:

Sven Bader (1x)


Admins  |  AGB  |  Applications  |  Autori  |  Chat  |  Informativa sulla privacy  |  Download  |  Entrance  |  Aiuto  |  Merchantportal  |  Impronta  |  Mart  |  Interfaces  |  SDK  |  Services  |  Giochi  |  Cerca  |  Support

Ein Projekt aller XProfaner, die es gibt!


Il mio XProfan
Private Notizie
Eigenes Ablageforum
Argomenti-Merkliste
Eigene Beiträge
Eigene Argomenti
Zwischenablage
Annullare
 Deutsch English Français Español Italia
Traduzioni

Informativa sulla privacy


Wir verwenden Cookies nur als Session-Cookies wegen der technischen Notwendigkeit und bei uns gibt es keine Cookies von Drittanbietern.

Wenn du hier auf unsere Webseite klickst oder navigierst, stimmst du unserer Erfassung von Informationen in unseren Cookies auf XProfan.Net zu.

Weitere Informationen zu unseren Cookies und dazu, wie du die Kontrolle darüber behältst, findest du in unserer nachfolgenden Datenschutzerklärung.


einverstandenDatenschutzerklärung
Ich möchte keinen Cookie