Assemblercodes für das neue X4

    Information: Kostenloser Download! Alle Neuerungen des Creators Updates in einem Flipbook Schau gleich mal rein!

    • Die "Spielereien" mit Arrays wären nicht komplett, wenn wir nicht sortieren könnten.


      Aufruf jeweils wieder mit 2 Parametern, der Erste die Anfangsadresse und der Zweite die Anzahl der Elemente. Kurze Beschreibung:
      Zeiger 1 zeigt auf das erste Element, Zeiger 2 zeigt auf das vorletzte Element. Verglichen werden immer das Element, auf das gezeigt wird und sein Nachfolger. Dann wird Zeiger 1 erhöht und Zeiger 2 erniedrigt bis alle Elemente durch sind. Nächster Durchlauf beginnt mit dem zweiten und dem vorvorletzten Element. Abgebrochen wird, wenn am Schleifenbeginn der Zeiger 2 kleiner als Zeiger 1 wird oder innerhalb eines Schleifendurchlaufs kein Element vertauscht werden mußte. Hat sowas auch einen Namen? ;-)

      Gruß Volkmar

      Edit: Auch die Korrektur zeigte noch Fehler, ich habe das Ganze erst mal raus genommen. Irgendwo ist da noch der Wurm drin

      Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von Volkmar () aus folgendem Grund: Code fehlerhaft

    • Neu

      Sowas nennt sich Bubblesort, denke ich. Das sind sicher keine "Spielereien", das sind sehr wichtige Beiträge von dir, Volkmar!

      Ich dagegen wollte x87-FPU-Code in den XASM einschleusen (- bin sicher, daß RGH das in einer kommenden XProfan-Version eingeplant hat, aber bis dahin dachte ich an eine Behelfslösung). Allein, ich bin bisher kläglich gescheitert, nicht am Code selbst, aber "von aussen" eingebracht sind Adressangaben zum laden und speichern der Register scheinbar nicht korrekt ermittelbar, schon gar nicht aus Labels.

      Ein Experimental-Sourcecode mit allen FPU-OpCodesequenzen (ohne Bytes zu Speicheradressierung) ist hier von meiner homepage zu laden, da wieder einmal die 10k-Grenze des Boards stark überschritten ist.

      Hat jemand eine Idee?
      Gruss

      P.S.: Natürlich müssen die Befehle noch (ev. nach Häufigkeit der Verwendung aufsteigend, und anschließend dominant ...) nach Länge absteigend sortiert werden, um korrektes parsing zu ermöglichen.

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

    • Neu

      Danke :-)
      Nichtdestotrotz, das Sortieren war bisher nur Spielerei, der Code war nicht stabil. Habe nun die Abbruchbedingung in den obigen Codes verändert, jetzt sollte es wirklich immer klappen.

      Gruß Volkmar

      Edit: Da ist noch immer der Wurm drin, ich habe die Codes erst mal raus genommen.
      Die überarbeitete Fassung gibts in #66

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

    • Neu

      Ja, die Fließkomma-Geschichte kommt. Bei mir ist es schon seit letztem Wochenende eingebaut und es funktionier derartiges schon:


      Quellcode

      1. ASM "DivTest", 2
      2. JMP Start
      3. Ergebnis:
      4. DD 0
      5. Start:
      6. FINIT
      7. FLD Par1 // oben auf den Stack
      8. FLD Par2 // oben auf den Stack
      9. FDIV // Stack1 / Stack0 - beide Werte vom Stack nehmen und Ergebnis auf den Stack
      10. FSTP [Ergebnis] // Ergebnis speichen und vom Stack nehmen
      11. MOV EAX,[Ergebnis]
      12. ENDASM
      13. Set("Decimals",6)
      14. Var single A = 2.25
      15. Var single B = 3
      16. Var single C = DivTest(A, B)
      17. Print C
      18. WaitInput
      19. End
      Alles anzeigen
      Wer einen HP-Rechner mit UPN nutze oder FORTH kennt, wird sich in der Stackgeschichte der FPU-Einheit des Prozesors zu Hause fühlen. ;-) Die 8 Register der FPU (ST0 bis ST7) fungieren nämlich als Stack.

      Aber dazu am Wochenende mehr. Und damit ist der Funktionsumfang von X4 weitgehend abgeschlossen.

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


      http://www.xprofan.de

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

    • Neu

      Jetzt nach einer Umorganisation der Abbruchbedingungen klappt es mit dem Sortieren ohne Fehler. Hinzugekommen ist noch der Rückgabewert -1, wenn versucht wird, ein Array mit weniger als 2 Elementen zu sortieren.

      Steigende Sortierung:

      Quellcode

      1. ASM "ArraySSort", 2
      2. // Array in steigender Richtung sortieren
      3. PUSH EBX
      4. PUSH ECX
      5. PUSH EDX
      6. PUSH EDI
      7. PUSH ESI
      8. MOV EDX, Par1 // Arrayadresse
      9. MOV EBX, Par2 // Arraygröße
      10. MOV EAX, -1
      11. CMP EBX, 2
      12. JNL @@OK
      13. JMP @@Fehler
      14. @@OK:
      15. MOV ECX, EDX // Anfang nach ECX
      16. SUB EBX, 2
      17. SHL EBX, 2 // Größe *4
      18. // Berechnet wird die Distanz vom ersten
      19. // zum vorletzten Element und diese dann
      20. // zur Anfangsadresse addiert
      21. ADD EDX, EBX // Endadresse berechnet
      22. MOV [@@Start], ECX
      23. MOV [@@Ende], EDX
      24. MOV EDI, ECX
      25. SUB EDI, 4
      26. JMP @@ASchleife
      27. @@Start:
      28. DD 0
      29. @@Ende:
      30. DD 0
      31. @@ASchleife:
      32. XOR ESI, ESI // Flag löschen
      33. CMP EDX, EDI // Zeiger 2 kleiner als Hilfszeiger
      34. JL @@fertig // JA -> raus
      35. @@ISchleife:
      36. MOV EAX, [ECX]
      37. MOV EBX, [ECX + 4]
      38. CMP EAX, EBX
      39. JL @@NoCh1
      40. // Vertauschen Wertpaar von Zeiger 1
      41. MOV [ECX], EBX
      42. MOV [ECX + 4], EAX
      43. INC ESI // Flag setzen
      44. @@NoCh1:
      45. ADD ECX, 4
      46. MOV EAX, [EDX]
      47. MOV EBX, [EDX + 4]
      48. CMP EAX, EBX
      49. JL @@NoCh2
      50. // Vertauschen Wertpaar von Zeiger 2
      51. MOV [EDX], EBX
      52. MOV [EDX + 4], EAX
      53. INC ESI // Flag setzen
      54. @@NoCh2:
      55. SUB EDX, 4
      56. CMP EDX, EDI
      57. JG @@ISchleife // noch nicht alle Werte durch
      58. // komplette Schleife durch
      59. OR ESI, ESI
      60. JZ @@Fertig // Flag nicht gesetzt -> Fertig
      61. // Nächste Schleifenwerte berechnen
      62. MOV ECX, [@@Start]
      63. MOV EDI, ECX
      64. ADD ECX, 4
      65. MOV [@@Start], ECX
      66. MOV EDX, [@@Ende]
      67. SUB EDX, 4
      68. MOV [@@Ende], EDX
      69. JMP @@ASchleife
      70. @@Fertig:
      71. XOR EAX, EAX // Rückgabewert 0, wenn sortiert wurde
      72. @@Fehler:
      73. POP ESI
      74. POP EDI
      75. POP EDX
      76. POP ECX
      77. POP EBX
      78. EndASM
      Alles anzeigen

      Fallende Sortierung:

      Quellcode

      1. ASM "ArrayFSort", 2
      2. // Array in steigender Richtung sortieren
      3. PUSH EBX
      4. PUSH ECX
      5. PUSH EDX
      6. PUSH EDI
      7. PUSH ESI
      8. MOV EDX, Par1 // Arrayadresse
      9. MOV EBX, Par2 // Arraygröße
      10. MOV EAX, -1
      11. CMP EBX, 2
      12. JNL @@OK
      13. JMP @@Fehler
      14. @@OK:
      15. MOV ECX, EDX // Anfang nach ECX
      16. SUB EBX, 2
      17. SHL EBX, 2 // Größe *4
      18. // Berechnet wird die Distanz vom ersten
      19. // zum vorletzten Element und diese dann
      20. // zur Anfangsadresse addiert
      21. ADD EDX, EBX // Endadresse berechnet
      22. MOV [@@Start], ECX
      23. MOV [@@Ende], EDX
      24. MOV EDI, ECX
      25. SUB EDI, 4
      26. JMP @@ASchleife
      27. @@Start:
      28. DD 0
      29. @@Ende:
      30. DD 0
      31. @@ASchleife:
      32. XOR ESI, ESI // Flag löschen
      33. CMP EDX, EDI // Zeiger 2 kleiner als Hilfszeiger
      34. JL @@fertig // JA -> raus
      35. @@ISchleife:
      36. MOV EAX, [ECX]
      37. MOV EBX, [ECX + 4]
      38. CMP EAX, EBX
      39. JG @@NoCh1
      40. // Vertauschen Wertpaar von Zeiger 1
      41. MOV [ECX], EBX
      42. MOV [ECX + 4], EAX
      43. INC ESI // Flag setzen
      44. @@NoCh1:
      45. ADD ECX, 4
      46. MOV EAX, [EDX]
      47. MOV EBX, [EDX + 4]
      48. CMP EAX, EBX
      49. JG @@NoCh2
      50. // Vertauschen Wertpaar von Zeiger 2
      51. MOV [EDX], EBX
      52. MOV [EDX + 4], EAX
      53. INC ESI // Flag setzen
      54. @@NoCh2:
      55. SUB EDX, 4
      56. CMP EDX, EDI
      57. JG @@ISchleife // noch nicht alle Werte durch
      58. // komplette Schleife durch
      59. OR ESI, ESI
      60. JZ @@Fertig // Flag nicht gesetzt -> Fertig
      61. // Nächste Schleifenwerte berechnen
      62. MOV ECX, [@@Start]
      63. MOV EDI, ECX
      64. ADD ECX, 4
      65. MOV [@@Start], ECX
      66. MOV EDX, [@@Ende]
      67. SUB EDX, 4
      68. MOV [@@Ende], EDX
      69. JMP @@ASchleife
      70. @@Fertig:
      71. XOR EAX, EAX // Rückgabewert 0 wenn sortiert wurde
      72. @@Fehler:
      73. POP ESI
      74. POP EDI
      75. POP EDX
      76. POP ECX
      77. POP EBX
      78. EndASM
      Alles anzeigen


      Gruß Volkmar
    • Neu

      Da hat Roland ja noch unbewußt ein Feature eingebaut.
      Ich verwalte ja gerne meine Werke, oder die
      aus dem Forum hier, in .inc Dateien.

      Besonders die ASM-Codes hier habe ich in einer eigenen
      Include gesammelt.

      In der .inc habe ich noch
      Set("ASMMODE", 1)
      stehen gehabt. Da hatte ich mal den
      RUN-Knopf bzw. Ausführen Interpreter gedrückt.
      Da hat er auch sämtliche .lst Dateien geschrieben.

      Für mich ist das ein Feature, wenn ich zur Include
      auch gleich sämtliche .lst Dateien habe. :top:
    • Neu

      Ich weiss ja nicht, warum meine eigenen Versuche alle fehlschlugen, aber seit RGH die 64-bit FPU-Lade- und Speicherbefehle implementiert hat, klappt das direkte Beladen von XProfans normalen Double Precision-Float-Zielvariablen ohne Probleme:

      Quellcode

      1. cls
      2. set("ASMMODE",0)
      3. ASM "TST4",2
      4. mov eax,par1 // In EAX ist die Adresse, an der der Double-Parameter steht
      5. mov ebx,par2 // In EBX ist die Adresse, an die das Ergebnis befördert werden soll
      6. FLD64 [eax] // Die 64Bit, die dort stehen, landen auf dem FPU-Stack ...
      7. FLD1 // Lade Wert 1 in neues ST0
      8. FADD // Addiere ST1 zu ST0, Wert nun in ST0
      9. FSTP64 [ebx] // *** und lade die Zielvariable direkt! ***
      10. mov eax,0 // Fehlercode könnte hier übergeben werden!
      11. ENDASM
      12. Set("DECIMALS",17) // (15 davon sind i.d.R. genau)
      13. declare P!,Q! // Q! MUSS declared sein, sonst kracht es!!!
      14. var P!=Pi()
      15. print "\n Übergabevariable P! ist derzeit ";P!
      16. print " Zielvariable Q! ist noch ";Q!
      17. print " Fehlermeldung (0=OK): ";Tst4(addr(P!),addr(Q!))
      18. print "\n ASM ausgeführt: Q! ist nun: ";q!
      19. print " Q! sollte nun Pi+1 sein. Differenz: ";Q! - (P!+1)
      20. print "\n Bei Differenz 0 hat das geklappt!"
      21. waitinput
      22. end
      Alles anzeigen


      P.S.: Ein Riesen-Danke!

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

    • Neu

      Hängt wahrscheinlich auch mit XProfans automatischer
      Typumwandlung zusammen :
      In der XProfan - Hilfe :

      Spoiler anzeigen

      Ab XProfan X2 können Fließkommawerte auch direkt an externe Funkltioonen übergeben werden, so lange diese nicht mit DEF definiert wurden, da sie dann automatisch vor der Übergabe in 32-Bit umgewandelt werden. Für mit DEF definierte externe Funktionen ist die Umwandlung mittels Single weiterhin notwendig.