ALGORITHMEN TEIL XII: Cogito errare est

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

    Information: Wir verlosen 9 Kinderbüchlein von Microsoft Mein Papa arbeitet bei Microsoft. Und ich darf mit!

    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.

    • Zum aktuellen Stand:

      Im Großen und Ganzen funktioniert mein Inline-Assembler schon.

      Quellcode

      1. window 1000,1000
      2. ASM "MeineFunktion", 2
      3. push ebp
      4. mov ebp,esp
      5. mov eax,par1
      6. mov ebx,par2
      7. add eax,ebx
      8. mov esp,ebp
      9. pop ebp
      10. ENDASM
      11. ' Var Long Ergebnis = MeineFunktion(34, 87)
      12. ' Print Ergebnis
      13. Print "Fertig!"
      14. WaitInput
      Alles anzeigen
      Er schreibt zwar das Programm noch nicht in den Speicher, aber erzeugt schon mal folgende Debug-Ausgabe:

      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. 5589E58B45088B5D0C01D889EC5D
      Alles anzeigen
      Das Bereitstellen des Speichers, das Schreiben der Bytes in den Speicher und das Hinzufügen der Funktion zu den importierten Funktionen ist dann wohl nur noch eine Fingerübung, die ich wegen der fortgeschrittenen Stunde auf morgen Abend verschiebe. Ach ja: Das "RET n", wobei n die Anzahl der Parameter * 4 ist, fehlt auch noch.

      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 ()

    • Viel mehr kann ich der Dokumentatation zu FASMDLL nicht entnehmen. Nur, daß er für das HalloWelt-Demo schon mal 8 MB Speicher reserviert hat. Der Beispielcode beginnt mit dem üblichen org 100h und macht nichts weiter als per INT21 den Text auszugeben, ist für uns also ohnehin nicht zu gebrauchen.

      Gruß Volkmar
    • Umgestrickt auf Prof-11, dank RGH läuft es nun auch da!
      Dankeeeee!

      Quellcode

      1. CLS:Declare Zeile$,err$,DLL&,Bereich#,Start&,Zahl&:Dim Bereich#,2048
      2. DLL&=ImportDLL("C:\\Users\\User\\AppData\\Roaming\\fasmDLL\\FASM.DLL","")
      3. Zeile$="\
      4. push ebp\n\
      5. mov ebp,esp\n\
      6. mov eax,[ebp + 8]\n\
      7. mov ebx,[ebp + 12]\n\
      8. add eax,ebx\n\
      9. add eax,ebx\n\
      10. mov esp,ebp\n\
      11. pop ebp\n\
      12. ret 8\z"
      13. ::::print " DLL geladen OK":beep:waitinput
      14. err$ = fasm_Assemble(addr(Zeile$),Bereich#,SizeOf(Bereich#),100,0) ' <<<<< Klappt jetzt
      15. Print err$
      16. Start&=long(Bereich#,8)
      17. Zahl& =long(Bereich#,4)
      18. Print "\n Code:",Zahl&,"Bytes"
      19. While Zahl&
      20. WhileLoop 8
      21. Print Right$("00"+Hex$(Byte(Start&,0)),2),
      22. Inc Start&
      23. Dec Zahl&
      24. CaseNot Zahl&:Break
      25. EndWhile
      26. Print
      27. EndWhile
      28. Dispose Bereich#
      29. FreeDll DLL&
      30. WaitInput
      31. End
      Alles anzeigen

      Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von p. specht ()

    • Versuche es mal mit Addr(Zeile$) als ersten Parameter. Ich weiß jetzt nicht auswendig, ab wann man das Addr() weglassen konnte.

      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
    • Roland meinte die fehlenden Zeilenumbrüche des
      XProfan-Quelltextes, wenn man diesen hier im
      Forumsbeitrag in den XProfedit kopiert. Den mußte
      ich auch erst trennen und neu zusammenklabustern.

      Hat nichts mit der Ausgabe des Programms zu tun.

      Das mit den Werten 66 und 67 kann ich auch
      bestätigen.

      PS: Da die DLL ja noch eine Funktion hat, die
      Dateien aktzeptiert, leg doch mal die paar Zeilen
      als Datei ab und laß dir den Output ausgeben.

      Quellcode

      1. fasm_AssembleFile(lpSourceFile,lpMemory,cbMemorySize,nPassesLimit,hDisplayPipe)
      Vielleicht kommen wir dann der Sache auf den Grund.

      Jetzt muß ich aber schnell zur Arbeit.

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

    • Ich denke mal, das hat folgenden Grund:

      Aus Kompatibilitätsgründen kennen 32-Bit-CPUs einen Modus um 16-Bit-Codes laufen zu lassen. (Ansonsten wäre es ja nicht möglich gewesen, auf Rechnern mit 32-Bit-CPU auch DOS oder Windows 31 laufen zu lassen.) Dafür zuständig ist der sogenannte PROECTED MODE der CPU. Andererseits ist es auch in diesem Modus möglich, die 32-Bit-Befehle zu nutzen. Dafür dienen wohl 66 bzw. 67 als Krennzeichen. Umgekehrt kann man im 32-Bit-FLAT MODE auch die 16-Bit-Varianten dieser Befehle nutzen, indem man die 66 voranstellt. (Es dürfte aber kaum Gründe geben dies zu tun.)

      So wie es asussieht, assembliert der FASM für den 16-Bit-Modus. Der erzeugte Code läuft daher nicht im 32-Bit-Modus.

      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
    • Jetzt hab' ich's!

      Wenn die erste Zeile USE32 ist, wird 32-Bit-Code erzeugt! Allerdings braucht der Assembler dann mehr als die mageren 1024 Byte an Speicher. Ich habe mal die in der Doku empfohlene Größe von $8000 eingestellt. Dann klappt es mit 32 Bit und das Ergebnis kann mit CALL aufgerufen werden. So funktioniert es:

      Quellcode: fasmtest.prf

      1. Declare String Zeile, err, Handle DLL
      2. Declare Memory Bereich
      3. Declare Pointer Start
      4. Declare Int Zahl
      5. Dim Bereich, $8000
      6. Cls
      7. DLL = ImportDLL("D:\\RGH\\FASM\\FASM.DLL", "")
      8. Zeile = "use32\n" + \
      9. "push ebp\n" + \
      10. "mov ebp, esp\n" + \
      11. "mov eax, [ebp + 8]\n" + \
      12. "mov ebx, [ebp + 12]\n" + \
      13. "add eax, ebx\n" + \
      14. "mov esp, ebp\n" + \
      15. "pop ebp\n" + \
      16. "ret 8\z"
      17. err = fasm_Assemble(Zeile, Bereich, SizeOf(Bereich), 100, 0)
      18. Print err
      19. Start = long(Bereich, 8)
      20. Zahl = long(Bereich, 4)
      21. Print
      22. Print "Code:", Zahl, "Bytes"
      23. Print
      24. // Aufruf des Codes
      25. Print call(Start, 45, 78)
      26. Print
      27. if Zahl > 0
      28. While Zahl
      29. WhileLoop 8
      30. Print Right$("00" + Hex$(Byte(Start,0)), 2),
      31. Inc Start
      32. Dec Zahl
      33. CaseNot Zahl : Break
      34. EndWhile
      35. Print
      36. EndWhile
      37. EndIf
      38. WaitInput
      39. Dispose Bereich
      40. FreeDll DLL
      41. 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
    • ... oder in XProfan-11:
      Spoiler anzeigen

      Quellcode

      1. Cls
      2. Declare Zeile$, err$, DLL%, Bereich#, Start%, Zahl&, Ver&, build&,a&,b&,c&
      3. Dim Bereich#, $8000
      4. DLL%=ImportDLL("C:\\Program Files (x86)\\XProfan11\\fasmDLL\\FASM.DLL","")
      5. Ver& = fasm_GetVersion():build&=ver&>>16:Ver& = Ver& and $FFFF
      6. font 2:print "\n Flat Assembler, DLL-Version ";ver&,"build: ";build&:font 0
      7. Zeile$ = "\
      8. use32 ; Erzeuge 32-bit-Code \n\
      9. jmp weiter \n\
      10. const1 dd 3,2,1 \n\
      11. weiter: push ebp \n\
      12. mov ebp, esp \n\
      13. mov eax, [ebp + 8] \n\
      14. mov ebx, [ebp + 12] \n\
      15. \
      16. add eax, ebx \n\
      17. add eax, ebx \n\
      18. \
      19. mov esp, ebp \n\
      20. pop ebp \n\
      21. ret 8 \z"
      22. err$ = fasm_Assemble(addr(Zeile$), Bereich#, SizeOf(Bereich#), 100, 0)
      23. if err$<>"0":Print err$
      24. sound 700,150:waitinput
      25. goto "Exxxit"
      26. endif
      27. Start% = long(Bereich#, 8)
      28. Zahl& = long(Bereich#, 4)
      29. Print
      30. Print " Code:",Zahl&,"Bytes"
      31. Print
      32. if Zahl&>0
      33. While Zahl&
      34. WhileLoop 8
      35. Print "$";Right$("00"+Hex$(Byte(Start%,0)),2);
      36. Inc Start%:Dec Zahl&:CaseNot Zahl&:Break
      37. print ",";
      38. EndWhile
      39. Print
      40. EndWhile
      41. EndIf
      42. font 2
      43. Print "\n Testlauf:"
      44. print "\n Asm-Funktion mit 2 Parametern dd "
      45. print "\n Par1 = ";:input a&
      46. print "\n Par2 = ";:input b&
      47. print "\n Sollwert = Par1+ 2 * Par2 = ";int(a&+2*b&)
      48. Print "\n Aufruf des OpCodes liefert: ";
      49. // Aufruf des Codes
      50. Print call(long(Bereich#,8), a&,b&)
      51. sound 1600,32
      52. WaitInput
      53. Exxxit:
      54. Dispose Bereich#
      55. FreeDll DLL%
      56. End
      Alles anzeigen

      Diese Fasm.dll stammt vom Sonntag, ‎06. ‎Dezember ‎2015, ‏‎10:11:34 und trägt die Versionsnummer 1.71.49.0. Interessant wäre allerdings, auf welcher Fasm-Vollversion sie beruht. Wenn die defaultmäßig noch auf 16-bit-Code arbeitet, dürfte sie vermutlich ziemlich alt sein...

      Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von p. specht ()

    • Sodele: Der Inline-Assembler von XProfan X4 funktioniert bei mir:

      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

      Das Ergebnis stimmt. Und das im Debug-Modus erzeugte Assembler-Listing sieht 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. Vopm ESP-Register (Stack) sollte man auf alle Fälle im Code die Finger lassen!
      Das Erzeugen des Assembler-Listing (Funktionsname + ".asm") werde ich über eine SET-Methode einstellbar machen.

      Jetzt gilt es noch, Fehler abzufangen, den Code fehler-toleranter zu gestalten, etc. (Leerzeichen vor oder nach dem '+' bei Offsets führen derzeit noch zum Absturz.)

      Kurz: Es sieht gut aus! Die Subscriptionsphase für X4 wird wohl noch im April starten.

      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

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

    • H.Brill schrieb:

      PS: Da die DLL ja noch eine Funktion hat, die
      Dateien aktzeptiert, leg doch mal die paar Zeilen
      als Datei ab und laß dir den Output ausgeben.
      Zusammen mit Rolands Tip (USE32) geht auch das. Ich hoffe, ich habe die Fehlerbehandlung einigermaßen hingekriegt. In einem Dialog kann eine *.ASM-Datei mit dem Quellcode gewählt werden. War der Vorgang erfolgreich, kann auf Nachfrage eine gleichnamige *.BIN-Datei erzeugt werden. Die enthält dann den Bytecode. Der könnte per BlockRead in einen Bereich geladen und mit CALL aufgerufen werden. Alternativ kann man den Bytecode ja auch als Ressource einbauen und von dort laden ;-)

      Quellcode

      1. Def %FASM_OK 0 ; FASM_STATE points to output
      2. Def %FASM_WORKING 1
      3. Def %FASM_ERROR 2 ; FASM_STATE contains error code
      4. Def $FASM_Errors "OK,arbeite,Fehler,\n\
      5. Ungültiger Parameter,\
      6. Zu wenig Speicher,\
      7. Stacküberlauf,\
      8. Quelle nicht gefunden,\
      9. Unerwartetes Codeende,\
      10. Formatgrenzen überschritten,\
      11. Code kann nicht erstellt werden,\
      12. Fehler beim Schreiben"
      13. Def $FASMERR "Datei nicht gefunden,\
      14. Lesefehler in Quelldatei,\
      15. Ungültiges Format in Quelldatei,\
      16. Ungültige Macroargumente,\
      17. Unvollständiger Macro,\
      18. Unerwartetes Zeichen,\
      19. Ungültiges Argument,\
      20. Illegale Instruktion,\
      21. Ungültiger Operand,\
      22. Unbekannte Operandengröße,\
      23. Fehlende Operandengröße,\
      24. Unpassende Operandengröße,\
      25. Ungültige Adressgröße,\
      26. Adressgröße unpassend,\
      27. Unzulässige Registerkombination,\
      28. Nicht codierbar,\
      29. Relativer Sprung außerhalb des Bereichs,\
      30. Ungültiger Ausdruck,\
      31. Ungültige Adresse,\
      32. Ungültiger Wert,\
      33. Wert außerhalb des zulässigen Bereichs,\
      34. Symbol nicht definiert,\
      35. Ungültige Symbolverwendung,\
      36. Name zu lang,\
      37. Ungültiger Name,\
      38. Schlüsselwort als Symbol verwendet,\
      39. Symbol bereits definiert,\
      40. Stringende fehlt,\
      41. Direktivenende fehlt,\
      42. Unerwartete Instruktion,\
      43. Unzulässige Zeichen,\
      44. Section nicht richtig ausgerichtet,\
      45. Einstellung bereits spezifiziert,\
      46. Daten bereits definiert,\
      47. Zu viele Wiederholungen,\
      48. Symbol außerhalb des Bereichs,,,,\
      49. Anwenderfehler,\
      50. Kommentar fehlerhaft"
      51. Declare String Datei, Ausgabe, err, Handle DLL
      52. Declare Memory Bereich
      53. Declare Pointer Start, Code
      54. Declare Int Zahl, Bytes
      55. Dim Bereich, 8000
      56. Cls
      57. DLL = ImportDLL("C:\Users\Volkmar\AppData\Roaming\\FASM.DLL", "") ' Pfad anpassen
      58. Datei = LoadFile$("ASM-Datei öffnen", "*.ASM")
      59. If Datei <> ""
      60. Ausgabe = Translate$(Upper$(Datei), ".ASM", ".BIN")
      61. err = fasm_AssembleFile(Datei, Bereich, SizeOf(Bereich), 100, 0)
      62. Start = long(Bereich, 8)
      63. Zahl = long(Bereich, 4)
      64. Code = Start
      65. Bytes = Zahl
      66. If err = %FASM_OK
      67. Print:Print "Code:", Zahl, "Bytes"
      68. While Zahl
      69. WhileLoop 8
      70. Print Right$("00" + Hex$(Byte(Start, 0)), 2),
      71. Inc Start
      72. Dec Zahl
      73. CaseNot Zahl : Break
      74. EndWhile
      75. Print
      76. EndWhile
      77. If MessageBox("Soll das Ergebnis in " + Ausgabe + " geschrieben werden?", "Codeausgabe", 36) = 6
      78. Assign #1, Ausgabe
      79. OpenRW #1
      80. BlockWrite #1, Bereich, Code - Bereich, Bytes
      81. If %IOResult
      82. MessageBox("Ausgabedatei konnte nicht geschrieben werden.", "Fehler", 16)
      83. Else
      84. Print Bytes, " Bytes wurden in " + Ausgabe + " geschrieben"
      85. EndIf
      86. Close #1
      87. EndIf
      88. WaitInput
      89. Else
      90. Fehlermeldung err, Zahl, Start
      91. EndIf
      92. EndIf
      93. Dispose Bereich
      94. FreeDll DLL
      95. End
      96. Proc Fehlermeldung
      97. Parameters Int Fehler, FehlerCode, Pointer Zeile
      98. Declare String Meldung, Long ZNr
      99. If Fehler < %FASM_OK
      100. Meldung = SubStr$($FASM_Errors, Abs(Fehler) + 3, ",")
      101. ElseIf Fehler = %FASM_ERROR
      102. ZNr = Long(Zeile, 4)
      103. Meldung = SubStr$($FASMERR, Abs(FehlerCode) - 100, ",") + " in Zeile " + Str$(ZNr, 0) + " in\n" + Upper$(String$(Long(Zeile, 0), 0))
      104. Else
      105. Meldung = SubStr$($FASM_Errors, Fehler, ",")
      106. EndIf
      107. Print "Code konnte nicht übersetzt werden!"
      108. MessageBox(Meldung, "FASM-Fehler", 16)
      109. EndProc
      Alles anzeigen
      Damit müssen Ungeduldige nicht auf X4 warten, um schon etwas basteln zu können ;-)


      Gruß Volkmar

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

    • Volkmar schrieb:

      ... auf Nachfrage eine gleichnamige *.BIN-Datei erzeugt werden. Die enthält dann den Bytecode. Der könnte per BlockRead in einen Bereich geladen und mit CALL aufgerufen werden.
      Das gilt aber nur, wenn es einem gelingt, stets relative Sprünge und Bezüge zu verwenden. Falls die in einem Programm erzeugte Bereichsvariable nämlich auch nur um 1 Byte woanders zu liegen kommt, geht die Sache ansonsten schief. Und leider ist die Wahrscheinlickeit, daß der dann anzuspringende Bereich in einem anderen Programm genau dort erzeugt wird, wohin die Mnemonics als OpCode damals hinein-assembliert wurden, verschwindend gering.

      Frage 1: Kann man bei FASM irgendwie sicherstellen, daß keine Absolutbezüge erzeugt werden? (Angeblich kann der uralte TASM das, also gab es zumindest mal diese Technik).

      ... oder:

      Frage 2: Kann ich irgendwie sicherstellen, daß der Bereich an der immer gleichen Stelle erzeugt wird, z.B. sofort am Hauptprogramm-Anfang? (Die Memory Management Unit stellt ja beim derzeitigen Windows Speichermodell jedem Programm virtuelle Speicheradressen von 0 bis AFFF FFFF FFFF FFFF zur Verfügung, oder so ähnlich oder dergleichen oder was, in Wirklichkeit keine Ahnung ...)

      Gruss ?!?!?!

      Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von p. specht ()

    • Da hast Du natürlich Recht, es gibt Einschränkungen. Die Adresse, an der der Code dann zu liegen kommt, kann man nicht beeinflussen. Und ansonsten gilt, nur "kleine Sprünge" machen. Aber solche "Kleinigkeiten", wie Roland in #132 vorgestellt hat, kann man durchaus machen. Für größere Sachen warten wir einfach ab, was Roland uns in X4 bietet. Oder ein Assemblerfuchs verrät uns ein paar "Verbiegungen". Oder Du nutzt eben Franks XPIA. Oder...?
      Wir wollten ja nur mal FASM unter Profan zum Laufen bringen.

      Gruß Volkmar
    • Und um diesen Thread nicht vollends zu kapern, geht es hier weiter:

      XProfan X4 mit Inlineassembler und mehr

      Dort gibt es auch den erwähnten Download!

      Gruß
      Roland

      ... und jetzt schaue ich etwas NHL-Eishockey!
      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
    • Abt. Komplexe Funktionen für Komplexe Zahlen
      ==============================
      Nachstehend eine in Profan-11 zum Laufen gebrachte Studie, wie man Komplexe Zahlen als Vier-Tupel darstellen kann und dadurch manche Funktionen (z.B. trigonometrische) leicht auf Komplexe Zahlen erweitern könnte (2 Teile, bitte zusammensetzen).
      Gruss

      Teil 1:

      Quellcode

      1. WindowTitle "PGM TComplex: Operationen mit Komplexen Zahlen (Re+j*Im)"
      2. ' Q:http://jean-pierre.moreau.pagesperso-orange.fr/Basic/tcomplex_bas.txt
      3. ' (D) Demo für eine Übertragung nach XProfan-11.2a. Ohne jede Gewähr!
      4. ' 2017-03 by P.Specht, Vienna/Austria. Mögliche Rechte Dritter ungeprüft.
      5. '
      6. ' A complex number Z is represented as an array with 4 locations:
      7. ' z(1), z(2) for algebraic form x+%j y = (x,y)
      8. ' z(3), z(4) for polar form r*exp(%i*t) = r versor t = (r \ t)
      9. WindowStyle 24
      10. Window %maxx*0.2,%maxy*0.1 - %maxx*0.6,%maxy*0.6
      11. font 2
      12. Declare ZZ![4],Z![4],Z1![4],Z2![4],temp![4],u![4] 'Complex numbers
      13. Declare tmp!,x!,y!,r!,t!,i&
      14. var XINF!=1.2E16 'big number
      15. var TINY!=val("1E-16")'small
      16. var PI!=4*ArcTan(1)
      17. var F$="#0.0000"
      18. x!=1 : y!=-2 : AssignXY(ZZ![],x!,y!):Z1![]=ZZ![&index]
      19. x!=2.5: y!=5.75 : AssignXY(ZZ![],x!,y!):Z2![]=ZZ![&index]
      20. AddCpx(ZZ![],Z1![],Z2![]):Z![]=ZZ![&index]
      21. PRINT "\n Z1 = ";:ZZ![]=Z1![&index]:DsplCpx(ZZ![])
      22. PRINT "\n Z2 = ";:ZZ![]=Z2![&index]:DsplCpx(ZZ![])
      23. PRINT "\n Z1+Z2 = ";:ZZ![]=Z![&index]:DsplCpx(ZZ![])
      24. PRINT "\n\n Z1+Z2 polar = ";:DsplCpxR(ZZ![])
      25. PRINT "\n Z1 polar = ";:ZZ![]=Z1![&index]:DsplCpxR(ZZ![])
      26. PRINT "\n Z2 polar = ";:ZZ![]=Z2![&index]:DsplCpxR(ZZ![])
      27. MulCpx(ZZ![],Z1![],Z2![])
      28. PRINT "\n\n Z1*Z2 = ";:DsplCpx(ZZ![])
      29. PRINT "\n Z1*Z2 polar = ";:DsplCpxR(ZZ![])
      30. DivCpx(ZZ![],Z1![],Z2![])
      31. PRINT "\n\n Z1 / Z2 polar = ";:DsplCpxR(ZZ![])
      32. ExpCpx(ZZ![],Z1![])
      33. PRINT "\n\n Exp(Z1) = ";:DsplCpx(ZZ![])
      34. PRINT "\n Exp(Z1) polar = ";:DsplCpxR(ZZ![])
      35. x!=2.5:y!=5.75 :AssignXY(ZZ![],x!,y!)
      36. Z1![]=ZZ![&index]
      37. AreaSinHypCpx(ZZ![],Z1![])
      38. PRINT "\n\n AreaSinHypCpx(Z2) = ";:DsplCpx(ZZ![])
      39. x!=1 : y!=-2 : AssignXY(ZZ![],x!,y!):Z1![]=ZZ![&index]
      40. x!=2.5: y!=5.75 : AssignXY(ZZ![],x!,y!):Z2![]=ZZ![&index]
      41. SubtrCpx
      42. PRINT "\n\n SubtrCpx(zz=z1-z2) = ";:DsplCpx(ZZ![])
      43. ChgSgnCpx
      44. PRINT "\n ChgSgnCpx(zz) = ";:DsplCpx(ZZ![])
      45. ConjugCpx
      46. PRINT "\n ConjugCpx(zz) = ";:DsplCpx(ZZ![])
      47. LnCpx
      48. PRINT "\n LnCpx(zz) = ";:DsplCpx(ZZ![])
      49. ExpCpx
      50. PRINT "\n ExpCpx(zz) = ";:DsplCpx(ZZ![])
      51. x!=1 : y!=2 :AssignXY(ZZ![],x!,y!):Z1![]=ZZ![&index]
      52. x!=0 : y!=1 :AssignXY(ZZ![],x!,y!):Z2![]=ZZ![&index]
      53. PowerCpx
      54. PRINT "\n PowerCpx(zz=z1^z2) = ";:DsplCpx(ZZ![])
      55. waitinput
      56. cls
      57. x!=1 : y!=2 :AssignXY(ZZ![],x!,y!):Z1![]=ZZ![&index]
      58. CosCpx(zz![],Z1![])
      59. PRINT "\n\n CosCpx(zz=cos Z1) = ";:DsplCpx(ZZ![])
      60. x!=1 : y!=2 :AssignXY(ZZ![],x!,y!):Z1![]=ZZ![&index]
      61. SinCpx(zz![],Z1![])
      62. PRINT "\n SinCpx(zz=sin Z1) = ";:DsplCpx(ZZ![])
      63. x!=1 : y!=2 :AssignXY(ZZ![],x!,y!):Z1![]=ZZ![&index]
      64. TanCpx(zz![],Z1![])
      65. PRINT "\n TanCpx(zz=tan Z1) = ";:DsplCpx(ZZ![])
      66. x!=1 : y!=2 :AssignXY(ZZ![],x!,y!):Z1![]=ZZ![&index]
      67. ArcCosCpx
      68. PRINT "\n\n ArcCosCpx (zz=acos Z1) = ";:DsplCpx(ZZ![])
      69. x!=1 : y!=2 :AssignXY(ZZ![],x!,y!):Z1![]=ZZ![&index]
      70. ArcSinCpx(zz![],Z1![])
      71. PRINT "\n ArcSinCpx(zz=asin Z1) = ";:DsplCpx(ZZ![])
      72. x!=1 : y!=2 :AssignXY(ZZ![],x!,y!):Z1![]=ZZ![&index]
      73. ArcTanCpx(zz![],Z1![])
      74. PRINT "\n ArcTanCpx(zz=atan Z1) = ";:DsplCpx(ZZ![])
      75. x!=1 : y!=2 :AssignXY(ZZ![],x!,y!):Z1![]=ZZ![&index]
      76. CoshypCpx
      77. PRINT "\n\n\n CoshypCpx(zz=cosh z1) = ";:DsplCpx(ZZ![])
      78. x!=1 : y!=2 :AssignXY(ZZ![],x!,y!):Z1![]=ZZ![&index]
      79. SinhypCpx
      80. PRINT "\n SinhypCpx(zz=sinh z1) = ";:DsplCpx(ZZ![])
      81. x!=1 : y!=2 :AssignXY(ZZ![],x!,y!):Z1![]=ZZ![&index]
      82. TanhypCpx
      83. PRINT "\n TanhypCpx(zz=sinh z1) = ";:DsplCpx(ZZ![])
      84. x!=1 : y!=2 :AssignXY(ZZ![],x!,y!):Z1![]=ZZ![&index]
      85. AreaCoshypCpx
      86. PRINT "\n\n AreaCoshypCpx(zz=acosh z1) = ";:DsplCpx(ZZ![])
      87. x!=1 : y!=2 :AssignXY(ZZ![],x!,y!):Z1![]=ZZ![&index]
      88. AreaSinhypCpx
      89. PRINT "\n AreaSinhypCpx(zz=asinh z1) = ";:DsplCpx(ZZ![])
      90. x!=1 : y!=2 :AssignXY(ZZ![],x!,y!):Z1![]=ZZ![&index]
      91. AreaTanhypCpx
      92. PRINT "\n AreaTanhypCpx(zz=atanh z1) = ";:DsplCpx(ZZ![])
      93. PRINT:beep:Waitinput
      94. END
      95. Proc AssignXY 'def Complex ZZ by values x (=Re) and y (=Im)
      96. ZZ![1]=x!:ZZ![2]=y!
      97. ZZ![3]=SQRT(sqr(x!)+sqr(y!))
      98. IF x!=0
      99. IF y! > 0
      100. ZZ![4]=PI! / 2
      101. ELSEIF y!=0
      102. ZZ![4]=-PI! / 2
      103. ELSE
      104. ZZ![4]=0
      105. ENDIF
      106. ELSE
      107. ZZ![4]=ArcTan(y!/x!)
      108. IF x! < 0
      109. IF y! >= 0
      110. ZZ![4]=ZZ![4] + PI!
      111. ELSE
      112. ZZ![4]=ZZ![4] - PI!
      113. ENDIF
      114. ENDIF
      115. case ZZ![4] > PI!:ZZ![4]=ZZ![4] - 2 * PI!
      116. case ZZ![4] < (-PI!):ZZ![4]=ZZ![4] + 2 * PI!
      117. ENDIF
      118. EndProc
      119. Proc AssignRT 'define Cpx number by r and t in radians
      120. ZZ![3]=r!:ZZ![4]=t!
      121. case ZZ![4] > PI!:ZZ![4]=ZZ![4] - 2 * PI!
      122. case ZZ![4]<(-PI!):ZZ![4]= ZZ![4] + 2 * PI!
      123. ZZ![1]=r! * COS(t!):ZZ![2]=r! * SIN(t!)
      124. endproc
      125. Proc DsplCpx 'Dspl Cpx number with x and y
      126. PRINT "("+format$(F$,ZZ![1])+" +j* "+format$(F$,ZZ![2])+")";
      127. Endproc
      128. Proc DsplCpxR 'Dspl Cpx number with radius and phase in radians
      129. PRINT "("+format$(F$,ZZ![3])+" \ "+format$(F$,ZZ![4])+")";
      130. Endproc
      131. Proc AddCpx 'add two Cpx numbers:ZZ=Z1+Z2
      132. ZZ![1]=Z1![1] + Z2![1]:ZZ![2]=Z1![2] + Z2![2]
      133. x!=ZZ![1]:y!=ZZ![2]
      134. AssignXY(ZZ![],x!,y!)
      135. EndProc
      136. Proc SubtrCpx 'subtract two Cpx numbers:ZZ=Z1-Z2
      137. ZZ![1]=Z1![1] - Z2![1]:ZZ![2]=Z1![2] - Z2![2]
      138. x!=ZZ![1]:y!=ZZ![2]:AssignXY(ZZ![],x!,y!)
      139. EndProc
      140. Proc ChgSgnCpx 'change sign of a Cpx number:ZZ=-ZZ
      141. ZZ![1]=-1*ZZ![1]:ZZ![2]=-1*ZZ![2]
      142. x!=ZZ![1]:y!=ZZ![2]:AssignXY(ZZ![],x!,y!)
      143. EndProc
      144. Proc ConjugCpx 'change sign of Im of a Cpx number
      145. ZZ![2]=-1*ZZ![2]
      146. x!=ZZ![1]:y!=ZZ![2]:AssignXY(ZZ![],x!,y!)
      147. EndProc
      148. proc MulCpx 'multiply two Cpx numbers:ZZ=Z1*Z2
      149. ZZ![3]=Z1![3] * Z2![3]:ZZ![4]=Z1![4] + Z2![4]
      150. r!=ZZ![3]:t!=ZZ![4]
      151. AssignRT(ZZ![],r!,t!)
      152. endproc
      153. Proc DivCpx 'divide two Cpx numbers:ZZ=Z1/Z2
      154. IF Z2![3] < TINY!
      155. ZZ![3]=XINF!
      156. ELSE
      157. ZZ![3]=Z1![3] / Z2![3]
      158. ENDIF
      159. ZZ![4]=Z1![4] - Z2![4]
      160. r!=ZZ![3]:t!=ZZ![4]
      161. AssignRT(ZZ![],r!,t!)
      162. endproc
      163. Proc ExpCpx 'exponential Cpx function:ZZ=Exp(Z1)
      164. IF EXP(Z1![1]) > XINF!
      165. tmp!=XINF!
      166. ELSE
      167. tmp!=EXP(Z1![1])
      168. ENDIF
      169. ZZ![1]=tmp! * COS(Z1![2]):ZZ![2]=tmp! * SIN(Z1![2])
      170. x!=ZZ![1]:y!=ZZ![2]
      171. AssignXY(ZZ![],x!,y!)
      172. EndProc
      173. Proc LnCpx 'ZZ=LN(Z1)
      174. IF Z1![3] <= 0
      175. ZZ![1]=-1*XINF!
      176. ELSE
      177. ZZ![1]=LN(Z1![3])
      178. ENDIF
      179. ZZ![2]=Z1![4]
      180. x!=ZZ![1]:y!=ZZ![2]
      181. AssignXY(ZZ![],x!,y!)
      182. EndProc
      183. Proc PowerCpx 'Cpx power ZZ=Z1^Z2
      184. LnCpx(temp![],Z1![])
      185. Whileloop 4:i&=&Loop
      186. Z1![i&]=Z2![i&]
      187. Z2![i&]=ZZ![i&]
      188. endwhile
      189. MulCpx(temp![],Z1![],temp![])
      190. Z1![]=ZZ![&index]
      191. ExpCpx(ZZ![],Z1![])
      192. EndProc
      Alles anzeigen
    • Teil 2 von 2:

      Quellcode

      1. Proc CosCpx 'ZZ=COS(Z1)
      2. ZZ![1]=(EXP(-1*Z1![2]) * COS(Z1![1]) + EXP(Z1![2]) * COS(-Z1![1])) / 2
      3. ZZ![2]=(EXP(-1*Z1![2]) * SIN(Z1![1]) + EXP(Z1![2]) * SIN(-1*Z1![1])) / 2
      4. x!=ZZ![1]:y!=ZZ![2]
      5. AssignXY(ZZ![],x!,y!)
      6. EndProc
      7. Proc SinCpx 'ZZ=SIN(Z1)
      8. ZZ![1]=(EXP(-Z1![2]) * SIN(Z1![1]) - EXP(Z1![2]) * SIN(-1*Z![1])) / 2
      9. ZZ![2]=-1*(EXP(-Z1![2]) * COS(Z1![1]) - EXP(Z1![2]) * COS(-1*Z![1])) / 2
      10. x!=ZZ![1]:y!=ZZ![2]
      11. AssignXY(ZZ![],x!,y!)
      12. EndProc
      13. Proc TanCpx 'ZZ=TAN(Z1)
      14. SinCpx(ZZ![],Z1![])
      15. temp![]=ZZ![&index]
      16. CosCpx(ZZ![],Z1![])
      17. whileloop 4:i&=&Loop
      18. Z1![i&]=temp![i&]
      19. Z2![i&]=ZZ![i&]
      20. endwhile
      21. DivCpx(ZZ![],Z1![],Z2![])
      22. EndProc
      23. Proc CoshypCpx 'ZZ=CH(Z1)
      24. ZZ![1]=(EXP(Z1![1]) * COS(Z1![2]) + EXP(-1*Z1![1]) * COS(-1*Z1![2])) / 2
      25. ZZ![2]=(EXP(Z1![1]) * SIN(Z1![2]) + EXP(-1*Z1![1]) * SIN(-1*Z1![2])) / 2
      26. x!=ZZ![1]:y!=ZZ![2]
      27. AssignXY(ZZ![],x!,y!)
      28. EndProc
      29. Proc SinhypCpx 'ZZ=SH(Z1)
      30. ZZ![1]=(EXP(Z1![1]) * COS(Z1![2]) - EXP(-1*Z1![1]) * COS(-1*Z1![2])) / 2
      31. ZZ![2]=-1*(EXP(Z1![1]) * SIN(Z1![2]) - EXP(-1*Z1![1]) * SIN(-1*Z1![2])) / 2
      32. x!=ZZ![1]:y!=ZZ![2]
      33. AssignXY(ZZ![],x!,y!)
      34. EndProc
      35. Proc TanhypCpx 'ZZ=TH(Z1)
      36. SinhypCpx(ZZ![],Z1![])
      37. temp![]=ZZ![&index]
      38. CoshypCpx(ZZ![],Z1![])
      39. whileloop 4:i&=&Loop
      40. Z1![i&]=temp![i&]
      41. Z2![i&]=ZZ![i&]
      42. Endwhile
      43. DivCpx(ZZ![],Z1![],Z2![])
      44. EndProc
      45. Proc ArcCosCpx 'ZZ=ARCCOS(Z1)
      46. Z![]=Z1![&index]
      47. temp![1]=1 - sqr(Z1![1]) + sqr(Z1![2])
      48. temp![2]=-2 * Z1![1] * Z1![2]
      49. x!=temp![1]:y!=temp![2]:AssignXY(ZZ![],x!,y!)
      50. Z1![]=ZZ![&index]
      51. x!=0.5:y!=0:AssignXY(ZZ![],x!,y!)
      52. Z2![]=ZZ![&index]
      53. PowerCpx(ZZ![],Z1![],Z2![])
      54. tmp!=ZZ![1]
      55. ZZ![1]=Z![1] - ZZ![2]
      56. ZZ![2]=Z![2] + tmp!
      57. x!=ZZ![1]:y!=ZZ![2]
      58. AssignXY(ZZ![],x!,y!)
      59. Z1![]=ZZ![&index]
      60. LnCpx(ZZ![],Z1![])
      61. tmp!=ZZ![1]
      62. ZZ![1]=ZZ![2]:ZZ![2]=-1*tmp!
      63. x!=ZZ![1]:y!=ZZ![2]
      64. AssignXY(ZZ![],x!,y!)
      65. EndProc
      66. Proc ArcSinCpx 'ZZ=ARCSIN(Z1)
      67. Z![]=Z1![&index]
      68. temp![1]=1 - sqr(Z1![1]) + sqr(Z1![2])
      69. temp![2]=-2 * Z1![1] * Z1![2]
      70. x!=temp![1]:y!=temp![2]
      71. AssignXY(ZZ![],x!,y!)
      72. Z1![]=ZZ![&index]
      73. x!=0.5:y!=0
      74. AssignXY(ZZ![],x!,y!)
      75. Z2![]=ZZ![&index]
      76. PowerCpx(ZZ![],Z1![],Z2![])
      77. ZZ![1]=ZZ![1] - Z![2]
      78. ZZ![2]=ZZ![2] + Z![1]
      79. x!=ZZ![1]:y!=ZZ![2]
      80. AssignXY(ZZ![],x!,y!)
      81. Z1![]=ZZ![&index]
      82. LnCpx(ZZ![],Z1![])
      83. tmp!=ZZ![1]
      84. ZZ![1]=ZZ![2]:ZZ![2]=-1*tmp!
      85. x!=ZZ![1]:y!=ZZ![2]
      86. AssignXY(ZZ![],x!,y!)
      87. EndProc
      88. proc ArctanCpx 'ZZ=ARCTAN(Z1)
      89. temp![1]=-Z1![1]:temp![2]=1 - Z1![2]
      90. u![1]=Z1![1]:u![2]=1 + Z1![2]
      91. x!=temp![1]:y!=temp![2]
      92. AssignXY(ZZ![],x!,y!)
      93. Z1![]=ZZ![&index]
      94. x!=u![1]:y!=u![2]
      95. AssignXY(ZZ![],x!,y!)
      96. Z2![]=ZZ![&index]
      97. DivCpx(ZZ![],Z1![],Z2![])
      98. Z1![]=ZZ![&index]
      99. LnCpx(ZZ![],Z1![])
      100. tmp!=ZZ![1]
      101. ZZ![1]=ZZ![2] / 2:ZZ![2]=-1*tmp! / 2
      102. x!=ZZ![1]:y!=ZZ![2]
      103. AssignXY(ZZ![],x!,y!)
      104. EndProc
      105. Proc AreacoshypCpx 'ZZ=ARGCH(Z1)
      106. Z![]=Z1![&index]
      107. temp![1]=-1 + sqr(Z1![1]) + sqr(Z1![2])
      108. temp![2]=2 * Z1![1] * Z1![2]
      109. x!=temp![1]:y!=temp![2]
      110. AssignXY(ZZ![],x!,y!)
      111. Z1![]=ZZ![&index]
      112. x!=0.5:y!=0
      113. AssignXY(ZZ![],x!,y!)
      114. Z2![]=ZZ![&index]
      115. PowerCpx(ZZ![],Z1![],Z2![])
      116. ZZ![1]=ZZ![1] + Z![1]
      117. ZZ![2]=ZZ![2] + Z![2]
      118. x!=ZZ![1]:y!=ZZ![2]
      119. AssignXY(ZZ![],x!,y!)
      120. Z1![]=ZZ![&index]
      121. LnCpx(ZZ![],Z1![])
      122. EndProc
      123. proc AreaSinHypCpx
      124. Z![]=Z1![&index]
      125. temp![1]=1 + sqr(Z1![1]) - sqr(Z1![2])
      126. temp![2]=2 * Z1![1] * Z1![2]
      127. x!=temp![1]:y!=temp![2]
      128. AssignXY(ZZ![],x!,y!)
      129. Z1![]=ZZ![&index]
      130. x!=0.5:y!=0:AssignXY(ZZ![],x!,y!)
      131. Z2![]=ZZ![&index]
      132. PowerCpx(ZZ![],Z1![],Z2![])
      133. x!=ZZ![1] + Z![1]:y!=ZZ![2] + Z![2]
      134. AssignXY(ZZ![],x!,y!)
      135. Z1![]=ZZ![&index]
      136. LnCpx(ZZ![],Z1![])
      137. Endproc
      138. Proc AreatanhypCpx 'ZZ=ARGTH(Z1)
      139. Z![]=Z1![&index]
      140. Z1![1]=1 + Z![1]:Z1![2]=Z![2]
      141. Z2![1]=1 - Z![1]:Z2![2]=-1*Z![2]
      142. x!=Z1![1]:y!=Z1![2]
      143. AssignXY(ZZ![],x!,y!)
      144. Z1![]=ZZ![&index]
      145. x!=Z2![1]:y!=Z2![2]
      146. AssignXY(ZZ![],x!,y!)
      147. Z2![]=ZZ![&index]
      148. DivCpx(ZZ![],Z1![],Z2![])
      149. Z1![]=ZZ![&index]
      150. LnCpx(ZZ![],Z1![])
      151. ZZ![1]=ZZ![1]/2:ZZ![2]=ZZ![2]/2
      152. x!=ZZ![1]:y!=ZZ![2]
      153. AssignXY(ZZ![],x!,y!)
      154. EndProc
      Alles anzeigen