Neue Antwort erstellen

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

Informationen
Frage Bitte beantworten Sie die untenstehende Frage bzw. lösen Sie die untenstehende Aufgabe.
Nachricht
Internet-Adressen werden automatisch erkannt und umgewandelt.
Smiley-Code wird in Ihrer Nachricht automatisch als Smiley-Grafik dargestellt.
Sie können BBCodes zur Formatierung Ihrer Nachricht nutzen.
Maximale Anzahl an Dateianhängen: unbegrenzt
Maximale Dateigröße: 20 MB
Erlaubte Dateiendungen: jpg, gif, png, tif, bmp

Vorherige Beiträge 71

  • Brackets(Text#, TextLänge%, Funktion%, AusgabePuffer#, AusgabePufferLänge%, Addr(KlammerPaar$))


    In Text# wird der zu untersuchende Text gestellt. Die Textlänge% kann -1 sein, wenn es sich um einen nullterminierten String handelt.
    Funktion% kann folgende Werte annehmen
    -2 ermittelt die Anzahl Klammerpaare, Ausgabepuffer# und AusgabePufferLänge% sollten 0 sein
    -1 ermittelt tiefste Klammerverschachtelung, Ausgabepuffer# und AusgabePufferLänge% sollten 0 sein
    1 .. n ermittelt Text in der angegebenen Klammernummer*, Rückgabewert ist die Verschachtelungsebene dieser Klammer
    KlammerPaar$ ist immer die Adresse eines Strings, der das gesuchte Klammerpaar enthält, also "()" oder "[]" oder "{}"

    Mögliche Fehlerwerte:
    -1 AusgabePuffer zu klein
    -2 Klammern in Text# nicht ausgewogen
    -3 KlammerPaar$ zu kurz (nur 1 Zeichen oder Leerstring)
    -4 KlammerPaar$ enthält zwei identische Zeichen
    -5 mehr als 255 Klammern sind nicht möglich
    -6 Funktion% ungültig (0 oder <-2)
    -7 Gesuchte Klammernummer nicht gefunden
    *Klammern werden immer von links nach rechts nach dem Auftreten der öffnenden Klammer gezählt

    Quellcode

    1. ASM "Brackets", 6
    2. PUSH EBX
    3. PUSH ECX
    4. PUSH EDX
    5. PUSH ESI
    6. PUSH EDI
    7. MOV ESI, Par1 // Eingabezeile
    8. MOV ECX, Par2 // Länge Eingabezeile oder -1
    9. MOV EDX, Par3 // Funktionsauswahl
    10. MOV EDI, Par4 // Ausgabepuffer
    11. MOV EBX, Par5 // Länge Ausgabepuffer
    12. MOV [OutLen], EBX
    13. MOV EBX, Par6 // Klammerstring
    14. JMP Start
    15. FM:
    16. DD 0 // Funktionsnummer oder Klammerzahl bei Kopieren
    17. KE:
    18. DD 0 // Klammerebene bei Kopieren
    19. OutLen:
    20. DD 0 // Merker Ausgabelänge
    21. Count: // Zählt nur die Klammerpaare
    22. NEG EDX
    23. MOV [FM], DL // Funktionsnummer zwischenspeichern
    24. XOR EDX, EDX // Zählregister löschen
    25. XOR EAX, EAX
    26. CS:
    27. LODSB
    28. DEC ECX
    29. JZ CEnde // Stringende erreicht
    30. OR AL, AL // Null-Byte?
    31. JZ CEnde // Ja: Stringende erreicht
    32. CMP AL, BH // Schließende Klammer
    33. JNE NSC
    34. DEC DL // Klammerzahl runterzählen
    35. JS COV // Klammerfehler (Vorzeichen negativ)
    36. NSC:
    37. CMP AL, BL // Öffnende Klammer
    38. JNE CS // Nein: Weitersuchen
    39. INC DL // Klammerzahl hochzählen
    40. INC AH
    41. CMP DL, DH
    42. JL NoBM
    43. MOV DH, DL // und merken, wenn nicht kleiner als bisherige Merkzahl
    44. NoBM:
    45. JMP CS
    46. CEnde:
    47. OR DL, DL
    48. JNZ COV // Klammerzähler <> 0 ist Klammerfehler
    49. MOV DL, [FM] // Funktionsnummer holen
    50. CMP DL, 1 // ist 1?
    51. JZ NBP // Ja, höchste Klammerzahl (Verschachtelungstiefe)
    52. MOV DH, AH // sonst Klammerpaare insgesamt
    53. NBP:
    54. XOR EAX, EAX
    55. MOV AL, DH // Ergebnis nach EAX
    56. JMP Ende // Abgeschlossen mit Klammerzahl in EAX
    57. COV:
    58. MOV EAX, -2 // Fehlercode -2: Klammern nicht ausgewogen
    59. JMP Ende
    60. // ############
    61. All: // Alle Klammerinhalte kopieren
    62. MOV EAX, -6 // Funktion 0 noch nicht implementiert
    63. JMP Ende
    64. // ############
    65. ZahlCopy: // einzelnen Klammerinhalt kopieren, EDX enthält Nummer der Klammer
    66. CMP EDX, 255
    67. JNA ZCCanSeek // gesuchte Klammernummer nicht größer als 255 ist erlaubt
    68. MOV EAX, -5 // ab Klammernummer 256 Fehler -5
    69. JMP Ende
    70. ZCCanSeek:
    71. OR EDI, EDI
    72. JNZ ZCNoMErr
    73. MOV EAX, -1
    74. JMP Ende
    75. ZCNoMErr:
    76. XOR EAX, EAX
    77. MOV AL, [OutLen]
    78. OR AL, AL
    79. JNZ ZCOSeekStart
    80. MOV EAX, -1 // Speicherfehler
    81. JMP Ende
    82. ZCOSeekStart:
    83. MOV AH, DL // zu suchende Klammernummer nach AH
    84. XOR EDX, EDX // Zählregister löschen
    85. MOV [KE], EDX
    86. ZCOSeek:
    87. LODSB
    88. OR AL, AL
    89. JZ ZCFertig1 // Wenn Nullbyte erkannt
    90. DEC ECX
    91. OR ECX, ECX
    92. JZ ZCFertig1 // Wenn Stringlänge durch
    93. CMP AL, BH
    94. JNZ ZCNoSK // keine schließende Klammer
    95. INC DH // schließende Klammer zählen
    96. PUSH EAX
    97. MOV EAX, [KE]
    98. DEC EAX
    99. MOV [KE], EAX
    100. POP EAX
    101. JMP ZCOSeek
    102. ZCNoSK:
    103. CMP AL, BL
    104. JNZ ZCNoOK // keine öffnende Klammer
    105. INC DL // öffnende Klammer zählen
    106. PUSH EAX
    107. MOV EAX, [KE]
    108. INC EAX
    109. MOV [KE], EAX
    110. POP EAX
    111. CMP AH, DL
    112. JE ZCCopy
    113. ZCNoOK:
    114. JMP ZCOSeek
    115. // hier dann Copyroutine, wenn DL = AH
    116. ZCFertig1: // Auffangpunkt Sprungdistanz
    117. JMP ZCFertig // weiterleiten
    118. ZCCopy:
    119. MOV [FM], 0 // Klammerzähler zurücksetzen
    120. ZCCopy1:
    121. LODSB
    122. OR AL, AL
    123. JZ ZCFertig1 // Wenn Nullbyte erkannt
    124. DEC ECX
    125. OR ECX, ECX
    126. JZ ZCFertig1 // Wenn Stringlänge durch
    127. CMP AL, BH
    128. JNZ ZCCNoSK // keine schließende Klammer
    129. INC DH // schließende Klammer zählen
    130. SUB [FM], 1 // gemerkte Klammerzahl runterzählen
    131. JLE CopyEnd // Kopierende
    132. ZCCNoSK:
    133. CMP AL, BL
    134. JNZ ZCSSeek
    135. INC DL // öffnende Klammer zählen
    136. ADD [FM], 1
    137. ZCSSeek:
    138. STOSB
    139. DEC [OutLen]
    140. JNZ ZCCopy1 // Ausgabepuffer nicht voll
    141. MOV EAX, -1 // sonst Speicherfehler
    142. JMP Ende
    143. ZCFertig:
    144. CMP DL, DH
    145. JE ZCNoBErr // öffnende und schließende Klammerzahl gleich
    146. MOV EAX, -2 // sonst Fehler Klammern nicht ausgewogen
    147. JMP Ende
    148. ZCNoBErr:
    149. MOV EAX, -7 // kein Fehler aufgetreten, nichts kopiert
    150. JMP Ende
    151. CopyEnd:
    152. XOR EAX, EAX // Nullbyte an Ausgabe anfügen
    153. STOSB
    154. MOV EAX,[KE] // Verschachtelungstiefe holen
    155. JMP Ende
    156. // ############
    157. Start: // Parameter prüfen und in Funktionsteile verzweigen
    158. OR EBX, EBX // ist Klammerstring 0?
    159. JZ BParErr // Klammerangabe zu kurz oder fehlt
    160. MOV AL, [EBX] // öffnende Klammer nach AL
    161. MOV BH, [EBX + 1] // schließende Klammer nach HB
    162. OR BH, BH // ist schließende Klammer NullByte?
    163. JNZ NoBParErr1 // Nein, kein Fehler
    164. BParErr:
    165. MOV EAX, -3 // Klammerangabe im Parameter zu kurz oder fehlt
    166. JMP Ende
    167. NoBParErr1:
    168. MOV BL, AL // öffnende Klammer nach BL
    169. CMP BL, BH // öffnende und schließende Klammer gleich?
    170. JNZ NoBParErr2 // Nein, kein Fehler
    171. MOV EAX, -4 // beide Klammern gleiches Zeichen
    172. JMP Ende
    173. NoBParErr2:
    174. // hier EDX auswerten und zur jeweiligen Funktion verzweigen
    175. CMP EDX, -1 // Funktion -1 durch Count bearbeitet
    176. JZ CountCall
    177. CMP EDX, -2 // Funktion -2 durch Count bearbeitet
    178. JZ CountCall
    179. // ab hier erst mal Fehler für ungültige Funktionen
    180. OR EDX, EDX
    181. JNZ ZCopy // Funktion 1 .. n
    182. JMP All // Funktion 0
    183. MOV EAX, -6 // sonstige Funktionen noch nicht implementiert
    184. JMP Ende
    185. ZCopy:
    186. JMP ZahlCopy
    187. CountCall:
    188. JMP Count // hier nun Count aufrufen
    189. Ende:
    190. POP EDI
    191. POP ESI
    192. POP EDX
    193. POP ECX
    194. POP EBX
    195. EndASM
    Alles anzeigen

    Gruß Volkmar
  • GetQuota(Text#, TextLänge%, Addr(Trenn$), ZitatNummer%, AusgabePuffer#, AusgabePufferLänge%)


    Text# wird nach Teilstrings untersucht, die in Zeichen entsprechend Trenn$ eingeschlossen sind. Trenn$ besteht immer aus 2 Zeichen, einem Zitatbeginn und einem Zitatende. Beide Zeichen können gleich sein, wenn zum Beispiel nach Textteilen in Anführungszeichen gesucht wird oder verschieden bei typografischen Anführungszeichen (Code 132, 147). Ist Textlänge% = 0, dann muß Text# einen nullterminierten String enthalten.
    Das Ganze erinnert zwar an SubStr$, ist aber doch etwas anders.
    Dieser "Text" wird nun "untersucht".
    Text ist das erste Zitat und untersucht das zweite Zitat.
    Das Zitat mit der gewünschten Nummer wird in AusgabePuffer# zurück gegeben. Der Rückgabewert ist dann die Anzahl Zeichen.
    Die ZitatNummer -1 beim Aufruf bewirkt, daß nur die Anzahl der im Text erkannten Zitate zurück gegeben wird.
    Wird AusgabePuffer# als 0 angegeben, wird die AusgabePufferLänge% ignoriert und es wird nur die Anzahl Zeichen des gewünschten Zitates oder ein Fehler zurückgegeben. Wird diese Zitatlänge benutzt, um den notwendigen AusgabePuffer# zu DIMmen, dann muß für das abschließende Nullbyte ein Byte mehr berücksichtigt werden, als DIM AusgabePuffer#, Rückgabe% + 1
    Mögliche Fehlerwerte:
    0 Gewünschtes Zitat nicht gefunden
    -1 Zweites Trennzeichen nicht gefunden (Zitat hat kein Ende, wurde deshalb nicht ermittelt)
    -2 AusgabePuffer zu klein
    -3 ZitatNummer% 0 oder kleiner -1 nicht erlaubt, (ZitatNummer% -1 ist erlaubt und hat eine besondere Bedeutung)


    Da die Trennzeichen variabel sind, könnte auch nach Klammern gesucht werden. Sind allerdings Klammern verschachtelt, funktioniert das nicht: 'Dieser (Text (wird)) untersucht' findet dann 'Text (wird' Für die Auflösung von Klammern sollte deshalb immer die Funktion Brackets() im nächsten Beitrag verwendet werden.

    Quellcode

    1. ASM "GetQuota", 6
    2. PUSH EBX
    3. PUSH ECX
    4. PUSH EDX
    5. PUSH ESI
    6. PUSH EDI
    7. MOV ESI, Par1 // Adresse Quellstring
    8. MOV ECX, Par2 // Länge Quellstring
    9. MOV EBX, Par3 // Adresse Trennzeichenstring (immer 2 Zeichen lang)
    10. MOV EDX, Par4 // Nummer des gesuchten Teilstrings
    11. MOV EDI, Par5 // Ergebnispuffer
    12. PUSH EDI
    13. MOV EDI, Par6 // Länge Ergebnispuffer
    14. PUSH EDI
    15. OR ECX, ECX // Quelllänge 0?
    16. JNZ IsLen // Nein, Länge ist angegeben in ECX
    17. DEC ECX // sonst auf -1 setzen damit maximale Länge bis 0-Byte
    18. OR EDX, EDX
    19. JZ CFehler
    20. IsLen:
    21. CMP EDX, -1
    22. JL CFehler
    23. MOV AL, [EBX] // Erstes Trennzeichen in AL
    24. MOV BH, [EBX + 1]// Zeites Trennzeichen in BH
    25. MOV BL, AL // Erstes Trennzeichen in BL
    26. OR BH, BH // Zweites Trennzeichen ist 0?
    27. JNZ StartSuche // Nein: Beginnen
    28. MOV BH, BL // sonst gleiches Zeichen wie erstes Zeichen
    29. StartSuche:
    30. MOV AH, BL // Suche erstes Trennzeichen
    31. S1:
    32. LODSB
    33. CMP AL, AH
    34. JZ F1 // Trennzeichen gefunden
    35. DEC ECX
    36. CMP ECX, -1
    37. JZ StrtFehler // Speicherende vor gefunden
    38. OR AL, AL
    39. JZ StrtFehler // Nullbyte = Textende
    40. JMP S1
    41. F1:
    42. MOV EDI, ESI // Stringanfang nach EDI
    43. EndeSuche:
    44. MOV AH, BH // Zweites Trennzeichen suchen
    45. S2:
    46. LODSB
    47. CMP AL, AH
    48. JZ F2 // Trennzeichen gefunden
    49. DEC ECX
    50. CMP ECX, -1
    51. JZ EndeFehler // Speicherende vor gefunden
    52. OR AL, AL
    53. JZ EndeFehler // Nullbyte = Textende vor gefunden
    54. JMP S2
    55. F2:
    56. DEC EDX // Gefunden, Teilstringnummer runter zählen
    57. JNZ StartSuche // Nicht der gesuchte Teilstring, nächsten Start suchen
    58. MOV EAX, ESI
    59. DEC EAX // EAX zeigt auf letztes Teilstringzeichen
    60. JMP Ausgabe
    61. CFehler:
    62. POP EAX // Stackkorrektur
    63. POP EAX // Stackkorrektur
    64. MOV EAX, -3 // Fehler setzen (ungültige Teilstringnummer) = -3
    65. JMP Ende
    66. StrtFehler:
    67. CMP EDX, 0
    68. JL Counter
    69. XOR EAX, EAX // Startfehler (Nicht gefunden) = 0
    70. JMP Fehler
    71. EndeFehler:
    72. CMP EDX, 0
    73. JL Counter // Teilstringzählen ausfiltern
    74. MOV EAX, -1 // Endefehler (Zweites Trennzeichen nicht gefunden) = -1
    75. Fehler:
    76. POP ECX // Länge Ergebnispuffer
    77. POP EDI // Adresse Ergebnispuffer
    78. OR EDI, EDI // kein Ausgabepuffer angegeben?
    79. JZ NoMemF // ist kein Fehler
    80. OR ECX, ECX // Ist 0?
    81. JZ MemFehler // Ja: Speicherfehler
    82. PUSH EAX
    83. XOR EAX, EAX // 0 als Ergebnisstring
    84. STOSB // 0 in Ausgabepuffer schreiben
    85. POP EAX
    86. NoMemF:
    87. JMP Ende
    88. MemFehler:
    89. MOV EAX, -2 // Fehler setzen (Speicher zu klein) = -2
    90. JMP Ende
    91. Counter:
    92. NOT EDX // Teilstringzahl umrechnen
    93. // setzt voraus, daß Anzahl als 1 angegeben war
    94. POP EAX // Stackkorrektur
    95. POP EAX // Stackkorrektur
    96. MOV EAX, EDX // Teilstringzahl nach Ergebnis
    97. JMP Ende
    98. Ausgabe: // kopiert gefundenen Teilstring in Ausgabepuffer
    99. SUB EAX, EDI // Teilstringlänge nach EAX
    100. MOV ESI, EDI // Anfang Teilstring nach ESI
    101. POP ECX // Länge Ergebnispuffer holen
    102. POP EDI // Anfang Ergebnispuffer holen
    103. OR EDI, EDI // Ergebnispuffer 0: Nur Teilstringlänge ermitteln?
    104. JZ Ende // JA, gleich beenden
    105. CMP EAX, ECX
    106. JNB MemFehler // Ergebnispuffer kleinergleich Teilstringlänge
    107. // muß ein Byte länger sein!
    108. PUSH EAX // Teilstringlänge notieren
    109. MOV ECX, EAX // und für REP nach ECX
    110. REPNZ
    111. MOVSB
    112. POP EAX // Teilstringlänge nach Rückgabe
    113. Ende:
    114. POP EDI
    115. POP ESI
    116. POP EDX
    117. POP ECX
    118. POP EBX
    119. EndASM
    Alles anzeigen
    Gruß Volkmar
  • 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.
  • 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!
  • 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:
  • 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
  • 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
  • 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
  • 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.