Tutorial
Inlineassembler in FreeBASIC
von Volta | Seite 6 von 9 |
Inlineassembler und Arrays
Ein Array bildet im Speicher eine Reihe von Variablen gleichen Typs. Die erste Adresse (Basis-Adresse) beinhaltet den Wert der Variablen mit dem kleinsten Index. Je nach Variablentyp steht die nächste Variable an der vorigen Adresse + 4 (SizeOf Integer = 4) . D.h. in unserem Beispiel lässt sich die Adresse zu einem Index so ausrechnen: Index*4 + Basis-Adresse
Dim Punkt (0 To 99) As Long
Dim As Integer l = UBound(Punkt)
Asm
lea ebx, [Punkt] 'Basis-Adresse
mov ecx, [l] 'UBound als Index
l_next:
lea esi, [ebx+ecx*4]'Basis-Adresse + (Index*4)
mov [esi], ecx
dec ecx
jnz l_next
End Asm
For i As Long = 0 To l
Print Punkt(i);" ";
Next
Sleep
Die Basis-Adresse wird in diesem Beispiel mit der Anweisung lea ebx, [Punkt] in das eax - Register geladen. Der Befehl lea Ziel, Quelle (load effective address) lädt die Adresse des Quelloperanden in das Ziel - Register. Als Quelle kann auch eine Kombination von Registern und Konstanten mit Addition und Multiplikation (nur 2,4,8,16 ...) eingesetzt werden.
Das kleine Beispiel belegt jedes Element des Arrays mit der Indexnummer. Na ja, nicht jedes Element Punkt(0) wird nicht bedacht, da wird schon bei der Initialisierung des Arrays null eingetragen.
Inlineassembler und UDTs
Wie beim Array bildet auch ein UDT im Speicher eine Reihe von Variablen, allerdings müssen die nicht gleichen Typs sein.
Die erste Adresse (Basis-Adresse) beinhaltet den Wert der ersten Definition im UDT. Je nach Variablentyp steht die nächste Variable an der 'vorigen Adresse + SizeOf Variablentyp' . D.h. jede Adresse muss individuell summiert werden, es sei denn, die Variablen des UDT sind alle vom gleichen Typ.
Type pnt
x As Long
y As Long
End Type
Dim Punkt As pnt
Punkt.x = 17
Punkt.y = 55
Print Punkt.x, Punkt.y
Asm
mov eax, [Punkt] 'eax = Punkt.x
add eax, [Punkt+4] 'eax + Punkt.y
Inc eax 'eax + 1
Shr eax, 1 'eax=(Punkt.x + Punkt.y +1)/2
mov [Punkt], eax 'Punkt.x = eax
mov [Punkt+4], eax 'Punkt.y = eax
End Asm
Print Punkt.x,Punkt.y
Sleep
UDTs an Prozeduren übergeben
Type pnt
x As Long
y As Long
End Type
Dim Punkt As pnt
Function mul_xy (ByRef zahl As pnt) As Integer
Asm
mov esi, [zahl] 'Adresse von zahl holen
mov eax, [esi] 'eax = zahl.x
imul eax, [esi+4] 'eax * zahl.y
mov [Function], eax 'als Funktionswert zurückgeben
End Asm
End Function
Punkt.x=17
Punkt.y=55
Print Punkt.x,Punkt.y
Print mul_xy(punkt)
Sleep
Inlineassembler und Strings
Ein String bildet im Speicher auch eine Reihe von Variablen gleichen Typs (Byte). Die erste Adresse (Basis-Adresse) zeigt auf das erste (linke) Zeichen des Strings.
'Die Funktion Revers spiegelt einen Text vom Anfang zum Ende.
'lt geändert in l, lt kann als Operator interpretiert werden.
Function Revers (ByVal txt As String) As String
Dim Text As String = txt
Dim l As Long = Len(Text)
If l > 1 Then
Asm
mov eax, [Text] 'Anfang des String im RAM
mov ecx, [l] 'Laenge des String
mov esi, eax 'erstes Zeichen des String'
Add eax, ecx
dec eax
mov edi, eax 'letzes Zeichen des String'
Shr ecx 'ecx = l \ 2 ;Laufvariable
lnext:
mov al, [esi] 'al = Anfang
mov ah, [edi] 'ah = Ende
mov [edi], al 'Ende = al
mov [esi], ah 'Anfang = ah
inc esi 'Anfang + 1
dec edi 'Ende - 1
Loop lnext 'wie for .. next
End Asm
End If
Function = Text
End Function
Dim t As String = "Dieser Text wird gespiegelt. Das ist 'just for fun' oder zum Verschluesseln?"
Print Revers(" !dlroW olleH ")
Print Revers(t)
Print t
t = Revers(t)
Print t
Sleep
Zusätzliche Informationen und Funktionen | |||||||
---|---|---|---|---|---|---|---|
|