| |
|
|
Sven Bader | Das Jonglieren con Datentypen kann en el Alltag nerven. Zum mejor Verständnis para mich incluso Yo algo con Rückgabewerten de OpenGL herumgespielt. Dankenswerterweise puede ser hay siempre zwischen Float, Double y Integer wählen. Mit 32-Bit Floats puede ältere XProfan Versionen sólo una vez nichts anfangen aber auch el bekommt uno hin!
Im Ejemplo frage Yo el maximale Größe para una gezeichneten Punkt de. Zurück kommt el Adresse uno Arrays con zwei Werten, mich interessiert jeweils el 2. Valor. En meiner Grafikkarte de paso 189.875
Yo habe Procs y Ensamblador Características geschrieben, en el interne Float() y Largo() a sustituir. Letztendlich tue Yo m Falle de Float 7x el gleiche en unterschiedlichen Wegen.
Es mein erster Ausflug a Ensamblador, por qué el Kommentare al Code todavía algo unbeholfen son. Letztendlich es genau para solche Speicher-Schubsereien ideal. Schneller como ihre Vorbilder long() y float() son el Características NICHT geworden.
Fazit: Über el Lerneffekt hinaus son folgende Wege el einfachsten y no langsamer como el ASM Code:
Verarbeitung uno 32-Bit Floats de una externo Aufruf mithilfe de long y double: float! = double(integer&) o. como Zona float! = double(long(bereich#,0)) Alternativ de XProfan X2, con el Datentyp Single trabajo.
Verarbeitung uno 64-Bit Floats (Double) de una externo Aufruf: Direkt, sin Konvertierung o. como Zona float! = float(bereich#,0)
Verarbeitung uno 32-Bit Integers de una externo Aufruf: Direkt, sin Konvertierung o. como Zona integer& = long(bereich#,0)
Jede Variable y Arrays puede como una Zona verwendet voluntad con Addr(): long(Addr(integer&[0],4) es el gleiche como integer&[1], Así que una Integer en Adresse des ersten Array-Elements + 4 Byte.
Mit Speicheradressen (Bereichsvariablen # y addr()) kann gerechnet voluntad: long(bereich#,4) es el gleiche como long(bereich# + 4,0)
Beim Herumspielen con Speicheradressen muss uno selbstverständlich aufpassen, como uno einerseits rápidamente encima deklarierte Bereiche hinausschießt oder incluso Werte con Speicheradressen verwechelt y irgendwo en el Speicher landet.
Cls
Declarar sizeRangeFloat#, sizeRangeInteger#, float!,sizeRangeArray![2],integerArray&[2]
Declarar single singleArray[2]' el va sólo 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]))'el va sólo seit X2
oGL("glGetFloatv", ~GL_POINT_SIZE_RANGE, Addr(integerArray&[0]))'Trick para ältere Profano-Versionen, lo folgt double()
oGL("glGetIntegerv", ~GL_POINT_SIZE_RANGE, sizeRangeInteger#)
oGL("Done")
Proc procLong
Parámetros a#, shift&
'en Tests no siempre korrekt
Volver ( (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 después de ecx
mov ebx, par2'par2 después de ebx
mov eax, [ebx]'par2 después de eax
mov [ecx], eax' eax después de par1
add ecx, 4' par1 Adresse + 4
mov edx, par3' par2 después de edx
mov eax, [edx]' par3 después de eax
mov [ecx], eax' eax después de par1
ENDASM
ASM "asmFloat", 2
mov eax, par2'par2 después de eax
mov edx, [eax]'4-Byte par2 (offset 0) después de edx schieben
mov eax, par1'par1 después de eax (Speicheradresse el Ziel Float-Variable)
mov [eax], edx
mov eax, par2'par2 después de eax
add eax, 4'Adresse + 4
mov edx, [eax]
mov eax, par1
add eax, 4'Adresse + 4
mov [eax], edx' eax (ahora+4) en par1 speichern
ENDASM
'Diese Función tut eigentlich nichts:
'ellos son el heraus, qué hineingeworfen ha
ASM "asmLong", 1
mov ecx, par1'par 1 después de ecx
mov eax, [ecx]'y unverändert ausgeben
ENDASM
'Diese Función tut eigentlich nichts:
'ellos son el heraus, qué hineingeworfen ha
ASM "asmLong2", 2
mov ecx, par1'par 1 después de ecx
mov ebx, par2'par 2 después de ebx
add ecx, par2'par 1 (ecx) y par2 addieren
mov eax, [ecx]'ausgeben
ENDASM
Def MoveMemory(3) !"kernel32.dll","RtlMoveMemory"
Proc procFloatMoveMemory
Parámetros dest!, source#
MoveMemory(addr(dest!),source#,8)
Volver dest!
ENDPROC
Proc procFloatLongLong
Parámetros dest!, source#
Largo addr(dest!),0 = long(source#,8),long(source#,12)
ENDPROC
Imprimir "\nFloats:"
'Offset jeweils en Byte 8, el es el zweite Array-Valor
'Float() Ensamblador-Variante
asmFloat(addr(float!), sizeRangeFloat# + 8)'direkte Zuweisung va desafortunadamente Aufgrund de 32-Bit Paremetern no
Imprimir float!
'Float() como interne XProfan-Función
Imprimir Float(sizeRangeFloat#,8)
'Float() como Proc con zwei long()
procFloatLongLong(float!,sizeRangeFloat#+8)'Direkte Rückgabe no posible, außer con float() y el debería sí eben ersetzt voluntad ;-)
imprimir str$(float!)
'Float() como Proc con MoveMemory
Imprimir procFloatMoveMemory(float!, sizeRangeFloat#+8)'Zuweisung posible aber el Variable en el 1. Paremeter se en cada Fall auch beschrieben
'Valor de Array (1 = zweiter Valor, como lo de 0 startet)
Imprimir sizeRangeArray![1]'Zuweisung posible aber el Variable en el 1. Paremeter se en cada Fall auch beschrieben
'Valor de Single-Array (32-Bit), Datentyp de X2 verfügbar
Imprimir singleArray[1]
'Valor de Integer-Array (32-Bit) como Double intepretiert. Es auch con älteren Profano Versionen
Imprimir double(integerArray&[1])
Imprimir "\nIntegers:"
'Largo() como Proc
Imprimir procLong(sizeRangeInteger#,4)'no siempre korrekt...
'Largo() como interne XProfan-Función
Imprimir Largo(sizeRangeInteger#,4)
'Largo() Ensamblador-Variante en un Parámetro (Adress-Offset muss incluso addiert voluntad)
Imprimir asmLong(sizeRangeInteger# + 4)
'Largo() Ensamblador-Variante con 2 Parametern, Offset kann como en el originalen Función transferencia voluntad
Imprimir asmLong2(sizeRangeInteger#, 4)
Disponer sizeRangeFloat#
Disponer sizeRangeInteger#
WaitKey
End
|
|
|
| |
|
|