Code-Beispiel
Tips und Tricks mit ASM-Anweisungen
Lizenz: | Erster Autor: | Letzte Bearbeitung: |
FBPSL | Volta | 29.11.2015 |
Tips und Tricks mit ASM-Anweisungen
Diese Macros / Functionen gibt es entweder als Befehl in FB nicht oder sind
mit Basicbefehlen nur umständlich zu bilden. In den vergangenen Jahren habe
ich sie mal gebraucht und jetzt hier zusammengestellt.
'rotiert eine Variable nach links um die angegebenen Anzahl Schritte
#Macro rol32(Variable, Anzahl)
Asm rol dword Ptr [Variable], Anzahl
#EndMacro
'rotiert eine Variable nach rechts um die angegebenen Anzahl Schritte
#Macro ror32(Variable, Anzahl)
Asm ror dword Ptr [Variable], Anzahl
#EndMacro
'bitweise gespiegelte Variable (abcde... -> ...edcba)
#Macro mirror32(Variable)
#Ifdef __FB_64BIT__
Asm
mov rax, [Variable]
mov ebx, 0
mov ecx, 32
1:
rcr eax
rcl ebx
dec ecx
jnz 1b
mov [Variable], rbx
End Asm
#Else
Asm
mov eax, [Variable]
mov ebx, 0
mov ecx, 32
1:
rcr eax
rcl ebx
dec ecx
jnz 1b
mov [Variable], ebx
End Asm
#EndIf
#EndMacro
'BSWAP nimmt eine Konvertierung vor, indem Byte 0 und Byte 3 sowie
'Byte 1 und Byte 2 gegeneinander ausgetauscht werden.
#Macro endian32(Variable) 'für alle 32Bit Werte (Integer, UInteger, Single)
#Ifdef __FB_64BIT__
Asm
mov rax, [Variable]
bswap eax
mov [Variable], rax
End Asm
#Else
Asm
mov eax, [Variable]
bswap eax
mov [Variable], eax
End Asm
#EndIf
#EndMacro
#Macro endian64(Variable) 'für alle 64Bit Werte (LongInt, ULongInt, Double)
#IFDEF __FB_64BIT__
Asm
mov rax, [Variable]
bswap rax
mov [Variable], rax
End Asm
#Else
Asm
mov edx, [Variable]
mov eax, [Variable+4]
bswap eax
bswap edx
mov [Variable], eax
mov [Variable+4], edx
End Asm
#EndIf
#EndMacro
#Macro dbl_SinCos(Angle, fbSin, fbCos) 'alle als Double
Asm
fld qword Ptr [Angle] 'Angle -> st(0)
fsincos 'compute sin AND cos
fstp qword Ptr [fbCos]'St(0) = cos -> fbCos
fstp qword Ptr [fbSin]'St(0) = sin -> fbSin
End Asm
#EndMacro
#Macro sgl_SinCos(Angle, fbSin, fbCos) 'alle als Single
Asm
fld dword Ptr [Angle] 'Angle -> st(0)
fsincos 'compute sin AND cos
fstp dword Ptr [fbCos]'St(0) = cos -> fbCos
fstp dword Ptr [fbSin]'St(0) = sin -> fbSin
End Asm
#EndMacro
'Eine Konstante z.B. Pi = ATN(1)*4 ist schneller
#Macro PI(Pi)
Asm fldpi 'pi -> st(0)
Asm fstp qword Ptr [Pi] 'St(0) -> PI
#EndMacro
Function Log2(x As Double ) As Double
'Return Log(x)/Log(2)
Asm
fld1 'get the multiplier, in this case 1
fld qword Ptr [x] 'get the operand
fyl2x 'calculate 1 * LOG2(operand) and pop stack
fstp qword Ptr [Function]'store the result and pop stack
End Asm
End Function
Function Log10(x As Double ) As Double
Asm
fld qword Ptr [x] 'get the operand
fldlg2 'Load log base 10 of 2
fxch st(1) 'Exchange st0, st1
fyl2x 'Compute the log base 10(x)
fstp qword Ptr [Function]'store the result and pop stack
End Asm
End Function
'Eine Version die angeblich genauer arbeitet
Function Log10a(x As Double ) As Double
Asm
fld1
fld qword Ptr [x]
fyl2x
fldlg2
fmulp
fstp qword Ptr [Function]
End Asm
End Function
'Für eine Farbreduzierung hatte ich ein Macro geschrieben aber
'Asm
' mov ebx, [pb]
' mov edx, [ps]
' mov ecx, [j]
' mov al, [ebx+2]
' Shl eax, 5
' mov al, [ebx+1]
' Shl eax, 6
' mov al, [ebx]
' Shr eax, 3
' mov [edx], ax
'End Asm
'ein neues Macro von Stonemonkey war noch schneller (weniger Speicherzugriffe).
#Macro Col24to16(ptr_s, ptr_d)
Asm
mov esi,[ptr_s]
mov edi,[ptr_d]
mov eax,[esi]'AAAAAAAARRRRRRRRGGGGGGGGBBBBBBBB
Shr ah, 2 'AAAAAAAARRRRRRRR00GGGGGGBBBBBBBB
ror eax,14 'GGGGGGBBBBBBBBAAAAAAAARRRRRRRR00
Shr ax, 5 'GGGGGGBBBBBBBB00000AAAAAAAARRRRR
rol eax,11 'BBB00000AAAAAAAARRRRRGGGGGGBBBBB
mov [edi],ax ' RRRRRGGGGGGBBBBB
End Asm
#EndMacro
#Macro Col16to24(rgb16, rgb32)
Asm
mov eax, dword Ptr [rgb16]
Xor ecx, ecx
mov cx, ax ' RRRRRGGGGGGBBBBB
ror ecx, 5 'BBBBB0000000000000000RRRRRGGGGGG
Shl cx, 2 'BBBBB00000000000000RRRRRGGGGGG00
ror ecx, 8 'GGGGGG00BBBBB00000000000000RRRRR
Shl cx, 3 'GGGGGG00BBBBB00000000000RRRRR000
ror ecx, 16 '00000000RRRRR000GGGGGG00BBBBB000
mov dword Ptr [rgb32], ecx
End Asm
#EndMacro
#Macro swap_date_format(x)
'Swap x[0],x[3]'von mm-dd-yyyy
'Swap x[1],x[4]'nach dd-mm-yyyy wandeln
Asm
mov edx, [x] 'mm-dd-yyyy
mov ax, [edx] 'dd ->ax
mov bx, [edx+3] 'mm ->bx
mov [edx+3], ax 'dd-dd-yyyy
mov [edx], bx 'dd-mm-yyyy
End Asm
#EndMacro
#Macro date_format(x)
'nach dd.mm.yyyy wandeln
Asm
mov edx, [x] 'mm-dd-yyyy
mov ax, [edx] 'dd ->ax
mov bx, [edx+3] 'mm ->bx
mov [edx+3], ax 'dd-dd-yyyy
mov [edx], bx 'dd-mm-yyyy
mov al, 46 '.
mov [edx+2], al 'dd.mm-yyyy
mov [edx+5], al 'dd.mm.yyyy
End Asm
#EndMacro
'Test ------------------------------------------
Width 100,20
Dim As integer zahl = &hfe0a
Print Bin(zahl, 32), Hex(zahl)
rol32(zahl, 10)
Print Bin(zahl, 32), Hex(zahl)
ror32(zahl, 10)
Print Bin(zahl, 32), Hex(zahl)
Print
mirror32(zahl)
Print Bin(zahl, 32), Hex(zahl)
mirror32(zahl)
Print Bin(zahl, 32), Hex(zahl)
Print
endian32(zahl)
Print Bin(zahl, 32), Hex(zahl)
endian32(zahl)
Print Bin(zahl, 32), Hex(zahl)
Print
Dim As LongInt lzahl = &hfe0afe0a
endian64(lzahl)
Print Bin(lzahl, 64), Hex(lzahl)
endian64(lzahl)
Print Bin(lzahl, 64), Hex(lzahl)
Print
Dim As Double Angle, fbSin, fbCos
PI(Angle)
Print Angle
Angle /=4 '=ATN(1)
dbl_SinCos(Angle, fbSin, fbCos)
Print fbSin
Print fbCos
Print Log2(10), 2^Log2(10)
Print Log10(1e7), 10^Log10(1e7)
Print Log10a(1e9), 10^Log10a(1e9)
Dim As String dt = Date
Print dt
swap_date_format(dt)
Print dt
dt = Date
date_format(dt)
Print dt
Sleep
Zusätzliche Informationen und Funktionen | |||||||
---|---|---|---|---|---|---|---|
|