Buchempfehlung
Mikrocomputertechnik mit Controllern der Atmel AVR-RISC-Familie
Mikrocomputertechnik mit Controllern der Atmel AVR-RISC-Familie
Umfassend, aber leicht verständlich führt dieses Buch in die Programmierung von ATMEL AVR Mikrocontrollern ein. [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!

Tutorial

Inlineassembler in FreeBASIC

von RedakteurVoltaSeite 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 (BefehlsreferenzeintragSizeOf 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 (BefehlsreferenzeintragByte). 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

 

Gehe zu Seite Gehe zu Seite  1  2  3  4  5  6  7  8  9  
Zusätzliche Informationen und Funktionen
  • Das Tutorial wurde am 09.08.2008 von RedakteurVolta angelegt.
  • Die aktuellste Version wurde am 25.04.2024 von RedakteurVolta gespeichert.
  Bearbeiten Bearbeiten  

  Versionen Versionen