XProfan X4 mit Inlineassembler und mehr

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    Unsere Datenschutzerklärung wurde aktualisiert. Mit der Nutzung unseres Forums akzeptierst Du unsere Datenschutzerklärung. Du bestätigst zudem, dass Du mindestens 16 Jahre alt bist.

    • XProfan X4 mit Inlineassembler und mehr

      Wie an anderer Stelle schon erwähnt, bastele ich derzeit an einen Inline-Assembler für XProfan X4. Bis zur offiziellen Subscription dauert es noch eine Weile, aber im Interpreter funktioniert der Inline-Assembler bereits. Und damit die Wartezeit bis zur Subscription nicht lang wird, gibt es den Interpreter PROFAN.EXE schon hier für alle zum kostenlosen Download:

      xprofan.de/download/XProfanX4alpha.zip

      Viel Spaß beim Ausprobieren. Einige Quellcodes liegen bei und werden hier im Thread von mir vorgestellt.

      Gruß
      Roland
      Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD / ATI Radeon HD4770 512 MB / Windows 7(32) - XProfan X4
      AMD Athlon II X2 2,9 GHz / 3 GB RAM / 500 GB HDD / ATI Radeon 3000 (onboard) / Windows 10(64) - XProfan X4


      http://www.xprofan.de

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von RGH ()

    • Ein erste Minimal-Assembler-Programm zum Addieren zweier Zahlen:

      Quellcode

      1. CLS
      2. ASM "MeineFunktion", 2
      3. mov eax,par1
      4. mov ebx,par2
      5. add eax,ebx
      6. ENDASM
      7. Var Long Ergebnis = MeineFunktion(38764, 879879878)
      8. Print Ergebnis
      9. Print "Fertig!"
      10. WaitInput
      Alles anzeigen

      Die Zahl hinter dem Funktionsnamen gibt die Anzahl der Parameter an. Diese ist wichtig, damit nach dem Aufruf korrekt "aufgeräumt" wird. Im Debug-Modus, der derzeit im Interpreter noch fix eingestellt ist, wird ein Assemblerlisting für jede ASM-Funktion ausgegeben. Der Dateiname ist der Funktionsname mit der Endung "lst". Dieses Listing sieht hioer so aus:

      Quellcode

      1. MeineFunktion - 2
      2. 0000 55 PUSH ebp
      3. 0001 89E5 MOV ebp,esp
      4. 0003 8B4508 MOV eax,par1
      5. 0006 8B5D0C MOV ebx,par2
      6. 0009 01D8 ADD eax,ebx
      7. 000B 89EC MOV esp,ebp
      8. 000D 5D POP ebp
      9. 000E C20800 RET 8
      10. 5589E58B45088B5D0C01D889EC5DC20800
      Alles anzeigen

      Das zwingend notwendige "PUSH EBP" und "MOV EBP,ESP" am Anfang, sowie das "MOV ESP,EBP" und "POP EBP" und das "RET x" fügt XProfan selbsttätig hinzu. Vom ESP-Register (Stack) sollte man auf alle Fälle im Code die Finger lassen!

      Par1 steht für [ebp + 8] (die Speicherstelle an der der erste Parameter abgelegt wird), Par2 für [ebp + 12], etc. Da wir uns in der 32-Bit-Welt befinden hat jeder Parameter eben 4 Byte! Der Wert in EAX ist der Rückgabewert der Funktion.

      Der ASM-Befehl assembliert den nachfolgenden Code bis ENDASM und fügt die Funktion der Liste der importierten Funktionen bei, so wie es auch ImportDLL und ImportFunc machen. Anschließend steht die Funktion dem Programm zur Verfügung.

      Gruß
      Roland
      Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD / ATI Radeon HD4770 512 MB / Windows 7(32) - XProfan X4
      AMD Athlon II X2 2,9 GHz / 3 GB RAM / 500 GB HDD / ATI Radeon 3000 (onboard) / Windows 10(64) - XProfan X4


      http://www.xprofan.de
    • Und hier ein etwas komplexeres Beispiel mit Sprüngen und Strings direkt aus dem XProfan-Quellcode (Verschlüsselungsroutine, basierend auf einem Assemblercode von Frank Abbing):

      Quellcode

      1. window 1000,1000
      2. declare string text, pw
      3. ASM "crypt", 2
      4. // Crypt proc
      5. PUSH EBX
      6. PUSH ESI
      7. PUSH EDI
      8. PUSH EBP
      9. // setze AnsiString-Pointer
      10. MOV EDX, Par1 // s
      11. MOV ECX, [edx-4] // len(s)
      12. MOV EBX, Par2 // pw
      13. MOV ESI, [ebx-4] // len(pw)
      14. MOV EDI,0
      15. @@jaguar:
      16. mov al,[edx]
      17. xor al,[ebx+edi]
      18. mov [edx],al
      19. inc edx
      20. inc edi
      21. cmp esi,edi
      22. jne @@kniez
      23. mov edi,0
      24. @@kniez:
      25. sub ecx,1
      26. jne @@jaguar
      27. XOR EAX, EAX
      28. POP EBP
      29. POP EDI
      30. POP ESI
      31. POP EBX
      32. ENDASM
      33. text = "Mein Text"
      34. pw = "Pass22"
      35. Var Long Ergebnis = Crypt(text, pw)
      36. Print Ergebnis
      37. Print text
      38. Crypt(text, pw)
      39. Print text
      40. WaitInput
      Alles anzeigen
      Die vier PUSH un POP am Anfnag/Ende kann man auch weglassen. Beim Delphi-Inline-Assembler sind sie empfehlenswert, da Delphi die Register auch zur Parameterübergabe nutzt. Die "@@" bei den Labels kann man auch weglassen. Ich habe den Teil eben einfach aus meinem Delphicode kopiert und lediglich "Par1" und "Par2" eingesetzt.

      Gruß
      Roland
      Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD / ATI Radeon HD4770 512 MB / Windows 7(32) - XProfan X4
      AMD Athlon II X2 2,9 GHz / 3 GB RAM / 500 GB HDD / ATI Radeon 3000 (onboard) / Windows 10(64) - XProfan X4


      http://www.xprofan.de
    • Und auch die Windows-API kann genutzt werden. Drei unterschiedliche Beispiele mit gleichem Ergebnis:

      Quellcode

      1. CLS
      2. Declare handle hDLL, Funk, String Text
      3. hDLL = UseDLL("USER32.DLL") ' Handle von USER32 ermitteln
      4. funk = ~GetProcAddress(hDLL, "MessageBoxA") ' Adresse der Funkton ermitteln
      5. ASM "MsgBox", 5 ' Ein Parameter Adresse + 4 Parameter für die Messagebox
      6. // Parameter einlesen
      7. MOV ECX, Par1
      8. MOV EAX, Par2
      9. MOV EDX, Par3
      10. MOV ESI, Par4
      11. MOV EBX, Par5
      12. // Messagebox-Parameter auf den Stack
      13. PUSH EBX
      14. PUSH ESI
      15. PUSH EDX
      16. PUSH EAX
      17. // Funktion aufrufen
      18. CALL ECX
      19. ENDASM
      20. Print MsgBox(funk, %hWnd, "Das ist die Botschaft!", "Titel", 51)
      21. waitinput
      Alles anzeigen
      Es geht auch mit weniger verschwenderischem Registerverbrauch:

      Quellcode

      1. $H windows.ph ' WindowsHeaderdatei nutzen
      2. CLS
      3. Declare handle hDLL, Funk, String Text
      4. hDLL = UseDLL("USER32.DLL") ' Handle von USER32 ermitteln
      5. funk = ~GetProcAddress(hDLL, "MessageBoxA") ' Adresse der Funkton ermitteln
      6. ASM "MsgBox", 5 ' Ein Parameter Adresse + 4 Parameter für die Messagebox
      7. // Parameter einlesen
      8. MOV EAX, Par5
      9. PUSH EAX
      10. MOV EAX, Par4
      11. PUSH EAX
      12. MOV EAX, Par3
      13. PUSH EAX
      14. MOV EAX, Par2
      15. PUSH EAX
      16. MOV EAX, Par1
      17. // Funktion aufrufen
      18. CALL EAX
      19. ENDASM
      20. Print Funk
      21. Print MsgBox(funk, %hWnd, "Das ist die Botschaft!", "Titel", 51)
      22. waitinput
      Alles anzeigen
      Und ein erstes Makro "FCALL" erlaubt den direkten Aufruf aller mit ImportFunc, ImportDLL und ASM importierten Funktionen:

      Quellcode

      1. $H windows.ph ' WindowsHeaderdatei nutzen
      2. CLS
      3. Declare handle hDLL, String Text
      4. hDLL = UseDLL("USER32.DLL") ' Handle von USER32 ermitteln
      5. ImportFunc(hDLL, "MessageBoxA", "")
      6. ASM "MsgBox", 4 ' 4 Parameter für die Messagebox
      7. // Parameter einlesen
      8. MOV EAX, Par4
      9. PUSH EAX
      10. MOV EAX, Par3
      11. PUSH EAX
      12. MOV EAX, Par2
      13. PUSH EAX
      14. MOV EAX, Par1
      15. PUSH EAX
      16. // Funktion aufrufen
      17. FCALL MessageBoxA
      18. ENDASM
      19. Print MsgBox(%hWnd, "Das ist die Botschaft!", "Titel", 51)
      20. waitinput
      Alles anzeigen
      Beim Assemblieren wird aus FCALL dann "MOV EAX, Funktionsadresse" und "CALL EAX", wie auch im erzeugten Listing zu sehen ist. Das EAX-Register bietet sich hier an, weil es ja ehr von der Funktion verändert wird und das Ergebnis aufnimmt.
      Ach ja: Bei der innerhalb Windows gültigen Aufrufkonvention STDCALL ist immer die Funktion für das Aufräumen des Stacks zuständig. Das heißt, die auf den Stapel geschobenen Parameter werden von der Funktion wieder von diesem entfernt. Für den Stapel gilt "Last In - First Out", daher wird der erste Parameter zuletzt auf den Stapel gelegt.

      Gruß
      Roland
      Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD / ATI Radeon HD4770 512 MB / Windows 7(32) - XProfan X4
      AMD Athlon II X2 2,9 GHz / 3 GB RAM / 500 GB HDD / ATI Radeon 3000 (onboard) / Windows 10(64) - XProfan X4


      http://www.xprofan.de

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von RGH ()

    • Hallo Roland,
      sieht ja schon mal sehr gut aus.

      Eine Frage vorab hätte ich noch :

      Könntest du das auch in eine PROC...ENDPROC verpacken ?

      Quellcode

      1. PROC XPos
      2. Parameters String such, text
      3. ' hier Parameterüberprüfung
      4. ASM "XPos", 2
      5. ' evtl. gleich : ASM "XPos", such, text
      6. .....
      7. .....
      8. ENDASM
      9. ENDPROC
      Wäre meiner Meinung nach übersichtlicher bzw. konformer.
      Es hätte auch einige Vorteile :
      - man könnte vorab schon die Parameter und deren Anzahl prüfen
      - Parameter-Typ prüfen evtl. abbrechen, Fehlermeldung usw.
      - bei optionalen Parametern evtl. vorbelegen
      - Fehlermeldung / Abbruch bei falschen Parametern
      - in Assembler ist sowas wohl eher schwieriger

      Das war das, was mir jetzt spontan einfiel.
      Man sieht es ja jetzt schon :
      Gib mal bei XPos eine Zahl statt eines Strings ein, egal ob 1. oder 2. Parameter.
      Da gibt es eine Schutzverletzung (Gott sei dank nicht mehr).

      Oder könnte man das in einer SET - Funktion ein/abschaltbar machen.
      Ich denke, wenn die ASM-Proc in einer Schleife aufgerufen wird, wird
      es wohl zu langsam. Anders, wenn eine ASM-Proc selber eine Schleife
      hat und nur einmal aufgerufen wird, macht es schon Sinn.

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von H.Brill ()

    • Den Bereich zwischen ASM und ENDASM (technisch gesehen handelt es sich um einen Befehl über mehrere Zeilen) in eine Prozedur zu packen, ist eine schlechte Idee, denn schließlich sollte der ASM-Befehl nur einmal aufgerufen werden, um die Funktion zu assemblieren und zur Verfügung zu stellen. Anschließend kann sie beliebig oft an beliebiger Stelle im Programm aufgerufen werden, genau so, wie etwa eine durch ImportFunc oder ImportDLL hinzugefügte Funktion. Es macht ja keinen Sinn diese mehrmals zu assemblieren.

      Allerdings steht es Dir frei, den Aufruf der neuen Funktion in eine Prozedur zu packen, um die Parameter zu überprüfen.

      Gruß
      Roland
      Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD / ATI Radeon HD4770 512 MB / Windows 7(32) - XProfan X4
      AMD Athlon II X2 2,9 GHz / 3 GB RAM / 500 GB HDD / ATI Radeon 3000 (onboard) / Windows 10(64) - XProfan X4


      http://www.xprofan.de
    • Ich sehe gerade :
      das geht :

      Quellcode

      1. Proc XPos
      2. Parameters String s, t
      3. ' Parameter prüfen
      4. xpos(s, t)
      5. EndProc
      Ich dachte anfangs, daß die Proc und die Asm-Proc kollidieren, weil sie den
      gleichen Namen haben.
      Mehr wollte ich eigentlich auch nicht.

      PS:
      Wie werden die Parameter eig. referenziert ?
      Bin da nicht so der Fachmann.

      Ich lese öfter :
      MOV ESI,OFFSET VARIABLE

      Reicht da z.B. ein : MOV ESI,PARAM1
      Oder kann man das anders machen ?

      Auch ein Elementzeiger z.B. für ein Array
      add eax,[esi+4*ecx] funktioniert noch nicht.

      Müßte man dann alles in Einzelschritten, indem man
      Werte in Register schiebt, bzw. multipliziert, machen.

      Vielleicht weiß jemnad ein paar Tipps.

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von H.Brill ()

    • Da es noch keine Doku gibt, ist es an der Zeit, zu erwähnen, welche Assembler-Befehle unterstützt werden:

      Befehle mit zwei Parametern:
      MOV ADD SUB TEST CMP XOR OR AND XCHG
      Erlaubte Parameter: REG,REG - REG,[REG] - REG,[REG+-n] - REG,[REG+REG] - REG,nn - REG,[nn] - [REG],REG - [REG+-n],REG - [nn],REG

      Befehle mit einem Parameter:
      INC DEC MUL IMUL DIV IDIV NOT NEG CALL JMP
      In der Regel erlaubte Parameter:REG - [REG] - [nn] - [REG+REG] - [REG+-n]
      Bei CALL und JMP zusätzlich: Label

      Bedingte Sprünge:
      JZ, JNZ, JE, JNE, JO, JNO, JA, JNA, JS, JNS, JL, JLE, JG, JGE, LOOP
      Hier ist als Parameter nur ein Label erlaubt. (Zur Zeit nur Short-Sprünge, d. h. maximale Sprungweite +-127.) Bei LOOP wird das ECX-Register um 1 heruntergezählt und der Sprung erfolgt, wenn es auf 0 kommt.

      Shift-Operationen
      RCL RCR ROR ROL SAL SAR SHL SHR
      Erlaubte Parameter: REG - REG,n (Wird n nicht angegeben, wird um 1 Bit verschoben)

      Sonstige:
      PUSH POP NOP RET
      Bei PUSH und POP muss ein Register als Parameter angegeben werden. Bei RET kann ein Integer als Parameter angegeben werden.

      REG steht für ein Register, n für einen Byte-Wert, nn für einen Long-Wert. Die eckigen Klammern für eine Speicher-Adresse. Bei MOV REG, REG wird also der Inhalt des zweiten Registers ins erste kopiert, bei MOV REG,[REG] hingegen der Inhalt an der Adresse, die das zweite Register angibt.

      Das sollte fürs Erste reichen! ;-)
      Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD / ATI Radeon HD4770 512 MB / Windows 7(32) - XProfan X4
      AMD Athlon II X2 2,9 GHz / 3 GB RAM / 500 GB HDD / ATI Radeon 3000 (onboard) / Windows 10(64) - XProfan X4


      http://www.xprofan.de

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von RGH ()

    • Eben gerade eine neue Version hochgeladen:

      Bei [REG+REG] wird jetzt auch die Skalierung unterstützt: [REG+REG*n].
      n darf die Werte 1, 2, 4 oder 8 haben. Die Schreibweise [REG+n*REG] ist nicht erlaubt.

      Gruß
      Roland
      Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD / ATI Radeon HD4770 512 MB / Windows 7(32) - XProfan X4
      AMD Athlon II X2 2,9 GHz / 3 GB RAM / 500 GB HDD / ATI Radeon 3000 (onboard) / Windows 10(64) - XProfan X4


      http://www.xprofan.de
    • Und hier etwas für die Mathematiker unter uns:

      Quellcode

      1. // Quelle des Assemblerlistings:
      2. // https://helloacm.com/fib-number-inline-assembly-delphi/
      3. CLS
      4. Declare int zahl
      5. ASM "Fibonacci", 1
      6. PUSH EBX
      7. MOV EAX,Par1
      8. TEST EAX, EAX
      9. JZ @M
      10. MOV ECX, EAX
      11. XOR EAX, EAX
      12. MOV EDX, 1
      13. @L:
      14. MOV EBX, EDX
      15. ADD EDX, EAX
      16. MOV EAX, EBX
      17. LOOP @L
      18. @M:
      19. POP EBX
      20. ENDASM
      21. For zahl,1,30
      22. Print Fibonacci(zahl)
      23. EndFor
      24. WaitInput
      25. End
      Alles anzeigen

      Gruß
      Roland
      Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD / ATI Radeon HD4770 512 MB / Windows 7(32) - XProfan X4
      AMD Athlon II X2 2,9 GHz / 3 GB RAM / 500 GB HDD / ATI Radeon 3000 (onboard) / Windows 10(64) - XProfan X4


      http://www.xprofan.de
    • Oh, ich denke, mehr als rudimentär ist er jetzt schon! ;-)

      Ach ja LOOPZ und LOOPNZ funktionierten auch schon!

      Neu dazugekommen in der eben hochgeladenen Version:

      CDQ ohne Parameter und LEA mit zwei Parametern, wobei der erste ein Register sein muss und der zweite keins sein darf.

      Bei PUSH und POP ist jetzt neben REG als Parameter auch [REG] erlaubt und bei PUSH darf als Parameter nun auch ein Integer angegeben werden, um gezielt einen Wert direkt auf den Stapel zu schieben.

      Außerdem ist bei den meisten Befehlen mit einem Parameter zusätzlich [Label] als Paramter erlaubt, während bei den meisten Befehlen mit zwei Parametern der erste nun auch [Label] sein kann oder der zweite [Label] oder Label.

      Zusätzlich gibt es folgende "Pseudo-Opcodes":

      DB n : fügt ein Byte ein
      DW nn : fügt ein Word (zwei Byte) ein
      DD nnnn : fügt ein Double-Word (vier Byte) ein
      DS "Text\z" : fügt einen String ein. Escape-Zeichen werden unterstützt. (Eingebettete Variablen natürlich nicht.)

      Ein kleines Beispiel:

      Quellcode

      1. CLS
      2. ASM "MulVar", 1
      3. jmp start
      4. var1:
      5. dd 22
      6. start:
      7. mov eax,par1
      8. mul [var1]
      9. ENDASM
      10. Var Long Ergebnis = MulVar(16)
      11. Print Ergebnis
      12. Print "Fertig!"
      13. WaitInput
      Alles anzeigen

      Gruß Roland
      Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD / ATI Radeon HD4770 512 MB / Windows 7(32) - XProfan X4
      AMD Athlon II X2 2,9 GHz / 3 GB RAM / 500 GB HDD / ATI Radeon 3000 (onboard) / Windows 10(64) - XProfan X4


      http://www.xprofan.de
    • Als etwas größeres Beispiel mit Strings: die abgwandelte MsgBox:

      Quellcode

      1. $H windows.ph ' WindowsHeaderdatei nutzen
      2. CLS
      3. Declare handle hDLL, String Text
      4. hDLL = UseDLL("USER32.DLL") ' Handle von USER32 ermitteln
      5. ImportFunc(hDLL, "MessageBoxA", "")
      6. ASM "MsgBox", 1 ' Ein Parameter Adresse + 4 Parameter für die Messagebox
      7. JMP Start
      8. Typ:
      9. DD 51
      10. Titel:
      11. DS "Titel Total!\z"
      12. Text:
      13. DS "Das ist auch ein Hinweis!\z"
      14. Start:
      15. // Parameter einlesen
      16. MOV EAX, [Typ]
      17. PUSH EAX
      18. MOV EAX, Titel
      19. PUSH EAX
      20. MOV EAX, Text
      21. PUSH EAX
      22. MOV EAX, Par1
      23. PUSH EAX
      24. // Funktion aufrufen
      25. FCALL MessageBoxA
      26. ENDASM
      27. Print MsgBox(%hWnd)
      28. waitinput
      Alles anzeigen

      Man beachte:
      Bei Typ steht der Wert an der durch das Label "Typ:" angegebenen Adresse. Die Funktion erwartet den direkten Wert, deshalb wird hier der Wert, der an dieser Adresse steht nach EAX geholt: Das Label steht in eckigen Klammern.
      Bei den Texten, steht der Text jeweils an der durch das Label angegebenen Adresse. Da die Funktion hier die Adressen der Strings erwartet, werden diese direkt nach EAX kopiert, also steht das Label hier ohne eckige Klammern.

      Ach ja: Die Strings sollten natürlich mit einem Null-Byte ("\z") aufhören, sonst wird es seltsam. Und für den Typ wird ein DD-Speicherplatz (4 Byte = 32 Bit) benötigt, da MOVE EAX, [Label] einen 32-Bit-Wert von der angegebenen Adresse holt. (Bei z.B. MOV AL,[Label] hätte auch DB für ein Byte genügt.)

      Gruß
      Roland
      Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD / ATI Radeon HD4770 512 MB / Windows 7(32) - XProfan X4
      AMD Athlon II X2 2,9 GHz / 3 GB RAM / 500 GB HDD / ATI Radeon 3000 (onboard) / Windows 10(64) - XProfan X4


      http://www.xprofan.de

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von RGH ()

    • Und das an sich unsinnige Beispiel zeigt, dass man die Werte an den mit Dx reservierten Speicherstellen auch verändern kann:

      Quellcode

      1. $H windows.ph ' WindowsHeaderdatei nutzen
      2. CLS
      3. Declare handle hDLL, String Text
      4. hDLL = UseDLL("USER32.DLL") ' Handle von USER32 ermitteln
      5. ImportFunc(hDLL, "MessageBoxA", "")
      6. ASM "MsgBox", 1
      7. JMP Start
      8. Typ:
      9. DD 51
      10. Titel:
      11. DS "Titel Total!\z"
      12. Text:
      13. DS "Das ist auch ein Hinweis!\z"
      14. Start:
      15. // Wert an Adresse TYP verändern
      16. MOV EBX, 18
      17. MOV [Typ],EBX
      18. // Parameter einlesen
      19. MOV EAX, [Typ]
      20. PUSH EAX
      21. MOV EAX, Titel
      22. PUSH EAX
      23. MOV EAX, Text
      24. PUSH EAX
      25. MOV EAX, Par1
      26. PUSH EAX
      27. // Funktion aufrufen
      28. FCALL MessageBoxA
      29. ENDASM
      30. Print MsgBox(%hWnd)
      31. waitinput
      Alles anzeigen
      Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD / ATI Radeon HD4770 512 MB / Windows 7(32) - XProfan X4
      AMD Athlon II X2 2,9 GHz / 3 GB RAM / 500 GB HDD / ATI Radeon 3000 (onboard) / Windows 10(64) - XProfan X4


      http://www.xprofan.de
    • Ich denke, das reicht erst mal für den Inline-Assembler.

      Die anderen Erweiterungen funktionieren im Interpreter auch schon:

      MAT Var[] < n : Initialisierung der Elemente mit Index*n.
      ZIP Zipfile$ : Erstellt ein ZIP-Archiv Zipfile$ aus den Deteien in der Listboxliste, ggf. mit Ordern.
      UNZIP Zipfile$, Zielordner$: Entpackt das ZIP-Archiv Zipfile$ in den Ordner Zielordner$, ggf. mit Unterordnern.
      db("slxxx", ....): Unterstützung von SQLite-Datenbanken. Es muss lediglich die aktuelle SQLITE.DLL im Pfad sein. Keine Installation nötig. Befehlsumfang ähnlich wie bei db("fbxxx", ...).

      Wenn als Ergebnisdatei für Select-Statements (Set("SQLFile", ...)) eine Datei mit der Endung ".xml" angegeben ist, wird das Ergebnis als XML-Datei erzeugt.

      Das wäre es für's Erste.

      Wenn ich den Inline-Assembler nun dem Compiler und der Runtime beigebracht habe, steht dem Start der Subscription für X4 nichts mehr im Wege.

      Gruß
      Roland
      Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD / ATI Radeon HD4770 512 MB / Windows 7(32) - XProfan X4
      AMD Athlon II X2 2,9 GHz / 3 GB RAM / 500 GB HDD / ATI Radeon 3000 (onboard) / Windows 10(64) - XProfan X4


      http://www.xprofan.de
    • super Roland.
      man braucht ja auch noch so einiges.
      Was ich etwas bedauerlich finde ist,,
      man findet sehr wenig für 32 Bit Asm. Auch Bücher
      gibt es kaum. Alles nur 16 Bit und jede Menge
      für Mikrcontroller (AVR, STM32 usw.)

      Was ich nach langem Suchen gefunden habe :

      Brainfuck-Quellcode

      1. ; ******************************************************
      2. ; DATEI: STRING.INC
      3. ; ==========
      4. ; VERS.: 0.01 (24.02.2014)
      5. ; 0.02 (27.02.2014)
      6. ; AUTOR: Eric Overheu
      7. ; ******************************************************
      8. ;
      9. ; API-FUNKTIONEN:
      10. ; ---------------
      11. ; - api_strcat {s1},{s2} Strings aneinanderhängen
      12. ; - api_strchr {s},{ch} Zeichen im String suchen
      13. ; - api_strcmp {s1},{s2} Strings vergleichen
      14. ; - api_strcpy {s1},{s2} String kopieren
      15. ; - api_strcspn {s1},{s2} Teilstring im String ermitteln
      16. ; - api_strlen {s} Stringlänge ermitteln
      17. ; - api_strncat {s1},{s2},{n} String mit n Zeichen aneinanderhängen
      18. ; - api_strncmp {s1},{s2},{n} n Zeichen von Strings vergleichen
      19. ; - api_strncpy {s1},{s2},{n} String mit n Zeichen kopieren
      20. ; - api_strpbrk {s1},{s2} erstes Auftreten eines bestimmten Zeichen
      21. ; - api_strrchr {s},{ch} letztes Auftreten eines bestimmten Zeichen
      22. ; - api_strspn {s1},{s2} erstes Auftreten eines nicht vorhanden Zeichen
      23. ; - api_strstr {s1},{s2} erstes Auftreten eines Teilstring im String
      24. ; - api_strtok {s1},{s2} String bei bestimmten Zeichen zerlegen
      25. ;
      26. ; ******************************************************
      27. strbuf TIMES 512 DB 0x0
      28. %MACRO api_strcat 2
      29. MOV ESI,%1
      30. MOV EDI,%2
      31. CALL strcat
      32. %ENDMACRO
      33. strcat: XOR ECX,ECX
      34. MOV EBP,ESI
      35. .lp1: LODSB
      36. OR AL,AL
      37. JZ .lp1d
      38. INC ECX
      39. JMP .lp1
      40. .lp1d: MOV ESI,EDI
      41. MOV EBX,ECX
      42. .lp2: LODSB
      43. OR AL,AL
      44. JZ .lp2d
      45. MOV [EBP+EBX],AL
      46. INC EBX
      47. JMP .lp2
      48. XOR AL,AL
      49. MOV [EBP+EBX],AL
      50. .lp2d: RET
      51. %MACRO api_strchr 2
      52. MOV ESI,%1
      53. MOV EBX,%2
      54. CALL strchr
      55. %ENDMACRO
      56. strchr: XOR ECX,ECX
      57. .lp: INC ECX
      58. LODSB
      59. OR AL,AL
      60. JZ .lpd0
      61. CMP AL,BL
      62. JE .lpd1
      63. JMP .lp
      64. .lpd0: XOR ECX,ECX
      65. .lpd1: RET
      66. %MACRO api_strcmp 2
      67. MOV ESI,%1
      68. MOV EBP,%2
      69. CALL strcmp
      70. %ENDMACRO
      71. strcmp: XOR EBX,EBX
      72. .lp: LODSB
      73. OR AL,AL
      74. JZ .lpd2
      75. MOV AH,AL
      76. MOV AL,[EBP+EBX]
      77. INC EBX
      78. CMP AH,AL
      79. JNZ .lpd1
      80. JMP .lp
      81. .lpd1: XOR EDX,EDX
      82. JMP .lpd3
      83. .lpd2: MOV EDX,1
      84. .lpd3: XOR EBX,EBX
      85. RET
      86. %MACRO api_strcpy 2
      87. MOV EBP,%1
      88. MOV ESI,%2
      89. CALL strcpy
      90. %ENDMACRO
      91. strcpy: XOR EBX,EBX
      92. .lp: LODSB
      93. OR AL,AL
      94. JZ .lpd
      95. MOV [EBP+EBX],AL
      96. INC EBX
      97. JMP .lp
      98. XOR AL,AL
      99. MOV [EBP+EBX],AL
      100. .lpd: RET
      101. %MACRO api_strcspn 2
      102. MOV ESI,%1
      103. MOV EBP,%2
      104. CALL strcspn
      105. %ENDMACRO
      106. strcspn: XOR ECX,ECX
      107. XOR EDX,EDX
      108. .lp1: XOR EBX,EBX
      109. INC ECX
      110. LODSB
      111. OR AL,AL
      112. JZ .lp1d0
      113. .lp2: MOV DL,BYTE [EBP+EBX]
      114. OR DL,DL
      115. JZ .lp1
      116. CMP AL,DL
      117. JE .lp1d1
      118. INC EBX
      119. JMP .lp2
      120. .lp1d0: XOR ECX,ECX
      121. .lp1d1: XOR EBX,EBX
      122. XOR EDX,EDX
      123. RET
      124. %MACRO api_strlen 1
      125. MOV ESI,%1
      126. CALL strlen
      127. %ENDMACRO
      128. strlen: XOR ECX,ECX
      129. .lp: LODSB
      130. OR AL,AL
      131. JZ .lpd
      132. INC ECX
      133. JMP .lp
      134. .lpd RET
      135. %MACRO api_strncat 3
      136. MOV ESI,%1
      137. MOV EDI,%2
      138. MOV ECX,%3
      139. CALL strncat
      140. %ENDMACRO
      141. strncat: PUSH ECX
      142. XOR ECX,ECX
      143. MOV EBP,ESI
      144. .lp1: LODSB
      145. OR AL,AL
      146. JZ .lp1d
      147. INC ECX
      148. JMP .lp1
      149. .lp1d: MOV ESI,EDI
      150. MOV EBX,ECX
      151. POP ECX
      152. .lp2: LODSB
      153. OR AL,AL
      154. JZ .lp2d
      155. MOV [EBP+EBX],AL
      156. INC EBX
      157. LOOP .lp2
      158. XOR AL,AL
      159. MOV [EBP+EBX],AL
      160. .lp2d: RET
      161. %MACRO api_strncmp 3
      162. MOV ESI,%1
      163. MOV EDI,%2
      164. MOV ECX,%3
      165. CALL strncmp
      166. %ENDMACRO
      167. strncmp: CMP ECX,0
      168. JNE .lp
      169. PUSH ESI
      170. PUSH EDI
      171. CALL strlen
      172. MOV EBX,ECX
      173. PUSH ESI
      174. MOV ESI,EDI
      175. CALL strlen
      176. POP ESI
      177. POP EDI
      178. POP ESI
      179. CMP ECX,EBX
      180. JNE .lpd0
      181. .lp: LODSB
      182. MOV AH,AL
      183. MOV AL,[ES:DI]
      184. INC DI
      185. CMP AH,AL
      186. JNZ .lpd0
      187. LOOP .lp
      188. .lpd1: MOV EDX,1
      189. RET
      190. .lpd0: XOR EDX,EDX
      191. RET
      192. %MACRO api_strncpy 3
      193. MOV EBP,%1
      194. MOV ESI,%2
      195. MOV ECX,%3
      196. CALL strncpy
      197. %ENDMACRO
      198. strncpy: XOR EBX,EBX
      199. .lp: LODSB
      200. OR AL,AL
      201. JZ .lpd
      202. MOV [EBP+EBX],AL
      203. INC EBX
      204. LOOP .lp
      205. XOR AL,AL
      206. MOV [EBP+EBX],AL
      207. .lpd: RET
      208. %MACRO api_strpbrk 2
      209. MOV ESI,%1
      210. MOV EBP,%2
      211. CALL strpbrk
      212. %ENDMACRO
      213. strpbrk: XOR ECX,ECX
      214. XOR EDX,EDX
      215. .lp1: XOR EBX,EBX
      216. INC ECX
      217. LODSB
      218. OR AL,AL
      219. JZ .lp1d0
      220. .lp2: MOV DL,BYTE [EBP+EBX]
      221. OR DL,DL
      222. JZ .lp1
      223. CMP AL,DL
      224. JE .lp1d1
      225. INC EBX
      226. JMP .lp2
      227. .lp1d0: XOR ECX,ECX
      228. .lp1d1: XOR EBX,EBX
      229. XOR EDX,EDX
      230. RET
      231. %MACRO api_strrchr 2
      232. MOV ESI,%1
      233. MOV EBX,%2
      234. CALL strrchr
      235. %ENDMACRO
      236. strrchr: XOR ECX,ECX
      237. XOR EDX,EDX
      238. .lp: INC ECX
      239. LODSB
      240. OR AL,AL
      241. JZ .lpd1
      242. CMP AL,BL
      243. JE .lpd2
      244. JMP .lp
      245. .lpd1: MOV ECX,EDX
      246. OR EDX,EDX
      247. JZ .lpd3
      248. JMP .lpd4
      249. .lpd2: MOV EDX,ECX
      250. JMP .lp
      251. .lpd3: XOR ECX,ECX
      252. .lpd4: XOR EDX,EDX
      253. RET
      254. %MACRO api_strspn 2
      255. MOV ESI,%1
      256. MOV EBP,%2
      257. CALL strspn
      258. %ENDMACRO
      259. strspn: XOR ECX,ECX
      260. XOR EDX,EDX
      261. .lp1: XOR EBX,EBX
      262. INC ECX
      263. LODSB
      264. OR AL,AL
      265. JZ .lp1d0
      266. .lp2: MOV DL,BYTE [EBP+EBX]
      267. OR DL,DL
      268. JZ .lp1d1
      269. CMP AL,DL
      270. JE .lp1
      271. INC EBX
      272. JMP .lp2
      273. .lp1d0: XOR ECX,ECX
      274. .lp1d1: XOR EBX,EBX
      275. XOR EDX,EDX
      276. RET
      277. %MACRO api_strstr 2
      278. MOV ESI,%1
      279. MOV EBP,%2
      280. CALL strstr
      281. %ENDMACRO
      282. strstr: XOR ECX,ECX
      283. .lp1: XOR EBX,EBX
      284. XOR EDX,EDX
      285. .lp2: INC ECX
      286. LODSB
      287. OR AL,AL
      288. JZ .lp3d
      289. .lp3: MOV DL,BYTE [EBP+EBX]
      290. OR DL,DL
      291. JZ .lp3d
      292. CMP AL,DL
      293. JNE .lp1
      294. INC EBX
      295. OR DH,DH
      296. JNZ .lp2
      297. MOV DH,CL
      298. JMP .lp2
      299. .lp3d: MOV CL,DH
      300. JMP .lp2d2
      301. .lp2d1: XOR ECX,ECX
      302. .lp2d2: XOR EBX,EBX
      303. XOR EDX,EDX
      304. RET
      305. %MACRO api_strtok 2
      306. MOV ESI,%1
      307. MOV EBP,%2
      308. CALL strtok
      309. %ENDMACRO
      310. strtok: XOR ECX,ECX
      311. XOR EDX,EDX
      312. PUSH ESI
      313. .lp1: XOR EBX,EBX
      314. INC ECX
      315. LODSB
      316. OR AL,AL
      317. JZ .lp1d0
      318. .lp2: MOV DL,BYTE [EBP+EBX]
      319. OR DL,DL
      320. JZ .lp1
      321. CMP AL,DL
      322. JE .lp2d
      323. INC EBX
      324. JMP .lp2
      325. .lp2d: XOR EBX,EBX
      326. XOR EDX,EDX
      327. ADD EDX,ECX
      328. .lp3: LODSB
      329. OR AL,AL
      330. JZ .lp3d
      331. MOV [strbuf+EBX],AL
      332. INC EBX
      333. INC EDX
      334. JMP .lp3
      335. .lp3d: POP ESI
      336. XOR AL,AL
      337. MOV [strbuf+EBX],AL
      338. MOV EBX,ECX
      339. DEC EBX
      340. .lp4: MOV AL,AL
      341. MOV [ESI+EBX],AL
      342. INC EBX
      343. CMP EBX,EDX
      344. JE .lp1d1
      345. JMP .lp4
      346. .lp1d0: POP ESI
      347. XOR ECX,ECX
      348. .lp1d1: XOR EBX,EBX
      349. XOR ECX,ECX
      350. XOR EDX,EDX
      351. RET
      Alles anzeigen
      Das ist mal für mich interessant, weil man es immer wieder braucht.
      Muß ich mich mal am Wochenende hinsetzen.

      Doch wie programmiert man ein
      LODSB
      und ein
      MOV DL,BYTE [EBP+EBX]
      um, sodaß es auch für die neue Asmfunktion von XProfan paßt ?

      Die Makros da drin sind ja kein Problem (%1 = Param1 usw.).
    • p. specht schrieb:

      Toll finde ich, dass Assemblerfehler so gut abgefangen werden. Sehr lehrreich!

      Bitte könnte man noch um mov [reg1+reg2*n],reg ergänzen?
      mov reg,[reg1+reg2*n] klappt ja schon!

      Gruss
      Ja kann man! Ist in der nächsten Version dabei. Das gilt dann natürlich für alle Befehle mit zwei Parametern.
      Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD / ATI Radeon HD4770 512 MB / Windows 7(32) - XProfan X4
      AMD Athlon II X2 2,9 GHz / 3 GB RAM / 500 GB HDD / ATI Radeon 3000 (onboard) / Windows 10(64) - XProfan X4


      http://www.xprofan.de
    • H.Brill schrieb:

      Doch wie programmiert man ein

      LODSB
      und ein
      MOV DL,BYTE [EBP+EBX]
      um, sodaß es auch für die neue Asmfunktion von XProfan paßt ?
      LODSB entspricht MOV AL,[ESI] gefolgt von einem INC ESI bzw. DEC ESI, je nachdem wie das Richtungsflag gesetzt ist.
      Und bei MOV AL, ... kann man das "BYTE" weglassen, da ja aufgrund des Ziels klar ist, dass es hier nur um ein Byte geht.

      In der nächsten Version werden dann auch LODSB und LODSD funktionieren. LODSD entsprich einem MOV EAX,[ESI] gefolgt von einem Erhöhen oder Erniedrigen des Index-Registers ESI um 4.

      Gruß
      Roland
      Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD / ATI Radeon HD4770 512 MB / Windows 7(32) - XProfan X4
      AMD Athlon II X2 2,9 GHz / 3 GB RAM / 500 GB HDD / ATI Radeon 3000 (onboard) / Windows 10(64) - XProfan X4


      http://www.xprofan.de