Neue Antwort erstellen

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.

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.

Vorherige Beiträge 81

  • Mal wieder zurück zum Thema: Assemblercodes!

    Hier ein kleiner trickreicher Code um die Bytes eines 32-Bit-Wertes in umgekehrte Reihenfolge zu bringen (z.B. Intel- in 68000-Format und umgekehrt):

    Quellcode

    1. CLS
    2. ' Set("AsmMode", 2)
    3. asm "SwapInt", 1
    4. mov edx,par1
    5. mov ah,dl
    6. mov al,dh
    7. shl eax,$10
    8. shr edx,$10
    9. mov ah,dl
    10. mov al,dh
    11. endasm
    12. var int wert = $11223344
    13. Print hex$(wert)
    14. Print hex$(SwapInt(wert))
    15. waitinput
    16. end
    Alles anzeigen

    Das kann z.B. auch im Zusammenhang mit MIDI (benutzt 68000 Format) interessant sein.

    Gruß
    Roland
  • Ach ja:

    Quellcode

    1. ds "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
    kann man auch einfacher schreiben:

    Quellcode

    1. dh "000102030405060708090A0B0C0D0E0F"
    Gruß
    Roland
  • Ok, bei mir klappt es jetzt. Das war nicht ganz einfach. Natürlich darf das Anführungszeichen im String nur als "\q" oder "\x22" vorkommen. Komma und Semikolon machen auch keine Probleme mehr.

    Ich werde demnächst also auch noch diesen Bugfix hochladen. Außerdem komme ich mit der Dokumentation ein wenig voran. Es wird zunächst eine PDF-Datei mit all den Neuerungen geben. Diese wird dann als Grundlage für das Erweitern der Hilfe dienen.

    Gruß
    Roland
  • Frage: Ich habe Probleme, dem Inline-ASM Interpreter die String charakters "=34 ,=44 und ;=59
    beizubringen. Der ds Befehl bricht mit Fehler ab, auch wenn man statt " \x22 verwenden will. Maskieren mit \ klappt auch nicht. Betrifft das nur den X4-Beta Interpreter?

    P.S.: Den Fehler ab Zeichen 128 macht das Board hier, d.h. der ist behebbar.

    Quellcode

    1. Windowtitle "Zugriffstest auf Zeichentabelle zeigt Diskrepanzen"
    2. Font 2:randomize:cls rnd(8^8)
    3. 'set("asmmode",2)
    4. ASM "Zugriffstest",1
    5. mov ecx,code
    6. jmp ecx
    7. Zeichen:
    8. ds "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
    9. ds "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"
    10. ds " !:#$%&'()*+:-./0123456789::<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^"
    11. ds "_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥"
    12. ds "¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß"
    13. ds "àáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ\x00"
    14. code:
    15. xor eax,eax
    16. mov ebx,Zeichen
    17. mov ecx,par1
    18. mov al,[ebx+ecx]
    19. EndASM
    20. print " Anführungszeichen "+chr$(34)+"=34 Komma ,=44 und Strichpunkt ;=59 machen Probleme!\n"
    21. Whileloop 0,255
    22. if &Loop<>Zugriffstest(&Loop)
    23. Print &Loop;":";Zugriffstest(&Loop)
    24. waitinput 1000
    25. endif
    26. endwhile
    27. beep
    28. WaitInput
    Alles anzeigen
  • Mit "Absolut" ist heute nicht eine fixe Speicheradresse gemeint, sondern eine erst zur Laufzeit zugewiesene Adresse. Relative Adressen (besser: Sprungdistanzen) können schon bei Assemblierzeit zugewiesen werden.
    Manchmal hilft es, Befehlsvarianten mit relativer Adressierung zu verwenden. Angeblich gibt es auch einen Assembler, der einen Schalter kennt, um nur relative Adressierungsarten zuzulassen (War das FASM ??)

    JMP weiter erzeugt z.B. den Code E9 JPL0000, nimmt also Laufzeitbezug auf L0000 Weiter. Für manche absoluten Befehle gibt es allerdings keine Ersatzmöglichkeiten.
    Gruss

    P.S.: Von Mitglied Jonathan stammt der Trick, im Assemblerprogramm nach dem absichtlich eingebauten Wert 12345678 zu suchen, um dahinter dann auf einen Datenbereich zuzugreifen. Clever!
  • Aber VORSICHT: Das kann nur mir Assemblercodes funktionieren, in denen keine absoluten Adressen vorkommen. Sobald ein z.B. CALL im Assemblercode vorkommt, geht es nicht mehr!

    Gruß
    Roland
  • Hallo,
    für alle, die noch X3 oder früher haben :
    Hier wäre es schön, wenn bei den veröffentlichten ASM-Procs
    auch die .lst - Datei dabei wäre, die mit Set("ASMMode", 1)
    automatisch erzeugt wird. Zumindest der am Ende erzeugte
    Bytestring. So hätten diese User auch was davon, da sie ja mit
    Call den gefüllten Bereich mit Bytes aufrufen können.

    In Anlehnung daran habe ich mir ein kleines Tool entwickelt,
    das man compiliert sehr gut im Benutzermenü integrieren
    kann.

    Quellcode

    1. Declare Handle btn1, btn2, f, String ASMStr, cnew
    2. Declare Long ende
    3. WindowTitle "Hex - Konvertierer"
    4. Window 600, 400
    5. btn1 = Create("Button", %HWnd, "Convert", 10, 10, 60, 25)
    6. btn2 = Create("Button", %HWnd, "Ende", 10, 60, 60, 25)
    7. UserMessages $10
    8. Clear ende
    9. WhileNot ende
    10. WaitInput
    11. If Clicked(btn1)
    12. ASMStr = Getclip$()
    13. If ASMStr <> ""
    14. cnew = ConvertBytes(ASMStr)
    15. AddWindows " XPROF"
    16. f = FindWindow(GetString$(0, 0))
    17. If f
    18. SendString(f, cnew)
    19. ende = 1
    20. 'MessageBox("In Editor kopiert !", "Info", 0)
    21. EndIf
    22. Else
    23. MessageBox("Bitte zuerst einen String\nin die Zwischenablage kopieren !", "Fehler", 0)
    24. EndIf
    25. ElseIf Clicked(btn2)
    26. ende = 1
    27. EndIf
    28. Case %UMessage = $10 : ende = 1
    29. EndWhile
    30. Proc ConvertBytes
    31. Parameters String bytefeld
    32. Declare String cstr
    33. WhileLoop 1, Len(bytefeld), 2
    34. cstr = cstr + "$" + Mid$(bytefeld, &LOOP, 2) + ","
    35. EndWhile
    36. cstr = Del$(cstr, Len(cstr), 1)
    37. Return cstr
    38. EndProc
    39. End
    Alles anzeigen
    Habe es jetzt nur im XProfed5.0 für X4 probiert. Beim älteren XProfed scheint das Benutzermenü
    nicht zu funktionieren.

    Vielleicht kann es ja jemand gebrauchen bzw. ausprobieren.


  • Zum Thema Assembler und Geschwindigkeit. Der folgende Code errechnet aus zwei Seitenlängen a und b und dem Winkel C (ang) die Seitenlänge c. Die Formel ist hier in XProfan-Schreibweise:

    c = sqrt(a^2 + b^2 - cos(ang) * 2 * a * b)

    (Da in Xprofan c und C die gleiche Variable wären, wurde für den Winkel ang genommen.)

    Brainfuck-Quellcode

    1. CLS
    2. // c^2 = a^2 + b^2 - cos(C)*2*a*b
    3. // C is stored in ang
    4. ASM "Triangle", 3
    5. JMP start
    6. a:
    7. dd 0 // length of side a
    8. b:
    9. dd 0 // length of side b
    10. ang:
    11. dd 0 // opposite angle to side c
    12. c:
    13. dd 0 // the result ? length of side c
    14. bak:
    15. dm 108
    16. start:
    17. mov eax, par1
    18. mov [a], eax
    19. mov eax, par2
    20. mov [b], eax
    21. mov eax, par3
    22. mov [ang], eax
    23. fsave [bak] // aktuellen FPU-Zustand sichern [-|-|-|-|-|-|-|-]
    24. fld [a] // a -> st0 [a|-|-|-|-|-|-|-]
    25. fld st0 // a in st0 + st1 [a|a|-|-|-|-|-|-]
    26. fmul // a^2 -> st0 [a^2|-|-|-|-|-|-|-]
    27. fld [b] // b -> st0 ; a^2 -> st1 [b|a^2|-|-|-|-|-|-]
    28. fld st0 // b in st0 + st1 ; a^2 -> st2 [b|b|a^2|-|-|-|-|-]
    29. fmul // st0 = b^2 ; a^2 -> st1 [b^2|a^2|-|-|-|-|-|-]
    30. fadd // st0 = a^2 + b^2 [a^2+b^2|-|-|-|-|-|-|-]
    31. fld [ang] // angle -> st0 [ang|a^2+b^2|-|-|-|-|-|-]
    32. fcos // st0 = cos(ang) [cos(ang)|a^2+b^2|-|-|-|-|-|-]
    33. fmul [a] // st0 = cos(ang) * a [cos(ang)*a|a^2+b^2|-|-|-|-|-|-]
    34. fmul [b] // st0 = cos(ang) * a * b [cos(ang)*a*b|a^2+b^2|-|-|-|-|-|-]
    35. fld st0 // st0 = cos(ang) * a * b ; st1 = cos(ang) * a * b [cos(ang)*a*b|cos(ang)*a*b|a^2+b^2|-|-|-|-|-|-]
    36. fadd // st0 = cos(ang) * a * b + cos(ang) * a * b = 2(cos(ang) * a * b) [2(cos(ang)*a*b)|a^2+b^2|-|-|-|-|-|-]
    37. fsub // st0 = st1 - st0 = (a^2 + b^2) - (2 * a * b * cos(ang)) [a^2+b^2-2(cos(ang)*a*b)|-|-|-|-|-|-|-]
    38. fsqrt // st0 = sqrt(st0) [sqrt(a^2+b^2-2(cos(ang)*a*b))|-|-|-|-|-|-|-]
    39. fstp [c] // st0 -> c [-|-|-|-|-|-|-|-]
    40. frstor [bak] // FPU-Zustand wiederherstellen
    41. mov eax, [c]
    42. ENDASM
    43. proc PTriangle
    44. Parameters double a, b, ang
    45. return sqrt(a^2 + b^2 - cos(ang) * 2 * a * b)
    46. EndProc
    47. declare long start
    48. declare single c
    49. print
    50. print "Vergleich ohne/mit Assembler"
    51. print "----------------------------"
    52. start = &gettickcount
    53. whileloop 10000
    54. c = PTriangle(4.56, 7.89, 1.5)
    55. endwhile
    56. print c,
    57. print "ohne: " + str$(&gettickcount - start)
    58. start = &gettickcount
    59. whileloop 10000
    60. c = Triangle(4.56, 7.89, 1.5)
    61. endwhile
    62. print c,
    63. print "mit: " + str$(&gettickcount - start)
    64. waitinput
    65. end
    Alles anzeigen

    Um die Zeiten zu vergleichen, wird das Dreieck 10000 mal berechnet. Auf meinem Firmen-Notebook dauert die reine XProfan-Variante ca. 360 Millisekunden und die Assembler-Variante nur ca. 140 Millisekunden.

    Zum besseren Verständnis ist der Code kommentiert und auch der jeweile FPU-Stack angegeben.

    FSAVE und FRSTOR sind hier im Beispiel nicht zwingend notwendig, garantieren aber auch bei verschachteltem Aufruf einen jungfräulichen FPU-Stack, da FSAVE den kompletten FPU-Zustand wegspeichert (es werden dafür mindestens 108 Bytes benötigt) und die FPU initialisiert. Mit FRSTOR wird der ursprüngliche Zustand wieder hergestellt.

    Gruß
    Roland