Buchempfehlung
Windows System Programming
Windows System Programming
Das Kompendium liefert viele interessante Informationen zur Windows-Programmierung auf Englisch. [Mehr Infos...]
FreeBASIC-Chat
Es sind Benutzer im FreeBASIC-Chat online.
(Stand:  )
FreeBASIC bei Twitter
Twitter FreeBASIC-Nachrichten jetzt auch über Twitter erhalten. Follow us!

Code-Beispiel

Code-Beispiele » Kleine Helferlein

Tips und Tricks mit ASM-Anweisungen

Lizenz:Erster Autor:Letzte Bearbeitung:
FBPSLRedakteurVolta 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
  • Das Code-Beispiel wurde am 23.10.2014 von RedakteurVolta angelegt.
  • Die aktuellste Version wurde am 29.11.2015 von RedakteurVolta gespeichert.
  Bearbeiten Bearbeiten  

  Versionen Versionen