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.

    • Die Sprünge sehen wie willkürlich herausgepickt aus.
      Kommen die anderen auch mit hinein?
      Sonst muss man sich für die Umsetzung eine Tabelle bereit legen.

      Quellcode

      1. <> JNE(*), JNZ (*)
      2. = JE (*), JZ (*)
      3. < JB ( ), JNAE( ), -- JL (*), JNGE ( ), -- JC ( ), JS (*)
      4. <= JBE( ), JNA (*), -- JLE(*), JNG ( )
      5. > JA (*), JNBE( ), -- JG (*), JNLE ( )
      6. >= JAE( ), JNB ( ), -- JGE(*), JNL ( ), -- JNC( ), JNS(*)
      7. CF JC ( ), JNC ( ) Carry
      8. OF JO (*), JNO (*) Overflow
      9. SF JS (*), JNS (*) Sign-Bit
      10. PF JP (*), JNP ( ) Parity
      Alles anzeigen

      Ich hatte hier
      ALGORITHMEN TEIL XII: Cogito errare est (#160)
      schon einen Teil davon aufgeführt.

      JL, JG werden als vorzeichenbehaftet (z.B. -128..+127)
      JB, JA werden als vorzeichenlos (z.B. 0..255) und
      JE, JZ als neutral betrachtet.

      Nutzt man die Sprünge in diesem Kontext, dann muss für XProfan nachträglich bearbeitet werden.
      Programmieren, das spannendste Detektivspiel der Welt.

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

    • Es gibt 16 verschiedene bedingte Sprünge, aber manche kommen unter mehreren Namen vor. So sind z.B. JE und JZ identisch (OpCode $74). Ich kann ja künftig die anderen Alternativen auch zulassen. Aber noch nicht in die soeben hochgeladenen Version.

      Da gibt es jetzt CALL Label (für CALLs innerhalb des Assemblercodes) und CALL nnnn (für CALLs nach außen innerhalb des Programmraumes). Eine importierte Funktion (durch ASM, ImportFunc oder ImportDLL) kann nun mit "CALL @name" aufgerufen werden, wodurch das Makro "FCALL name" überflüssig wird. Mit @name wird die Adresse der Funktion name ermittelt.

      JMP Label führt jetzt nicht mehr einen Short-Jump (+-127) aus, sondern einen Near-Jump (+-2147483647) aus. Damit sind auch größere Sprünge, z.B. über einen Datenblock am Anfang des Code möglich. An der Syntax ändert sich nichts. CALL Label funktioniert übrigens auch im Near-Bereich. Bei den bedingten Sprüngen bleibt es weiterhin bei den Short-Jumps.

      Es wurden einige Sonderfälle bei Verwendung von EBP und ESP innerhalb eckiger Klammern berücksichtigt, die bislang falschen Code erzeugten und zum Absturz führten. Wenn man EBP verwendet, sollte man zu Beginn des Programmes dessen Wert mit PUSH EBP sichern und am Ende wieder mit POP EBP zurückholen.

      Ach ja: die erwähnten Datenbereiche kann man mit dem Pseudo-Opcode DM nnnn anlegen, wobei nnnn Bytes mit dem Wert 0 eingefügt werden.

      Ich hoffe, ich habe nichts vergessen ...

      Gruß
      Roland

      PS: Und Labels können jetzt in der Mitte einer Zeile vorkommen:

      Quellcode

      1. cls:print "Anfang":goto "Ende":print "Mitte":Ende::print "Fertig":waitinput:end
      Es gibt dann halt zwei Doppelpunkte: Einen fürs Label und einen als Befehls-Trenner. Das Programm wird dadurch aber nicht wirklich lesbarer.
      (Intel Duo E8400 3,0 GHz / 4 GB RAM / 250 GB HDD / ATI Radeon HD4770 512 MB / Windows Vista - ausgemustert zum Verkauf)
      AMD Athlon II X2 2,9 GHz / 8 GB RAM / 500 + 1000 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 ()

    • Ach ja: Das Messagebox-Beispiel in der nun gültigen Form mit CALL:

      Quellcode

      1. Window 800,600
      2. Declare handle hDLL, String Text
      3. hDLL = UseDLL("USER32.DLL") ' Handle von USER32 ermitteln
      4. ImportFunc(hDLL, "MessageBoxA", "")
      5. set("ASMMODE",2)
      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. CALL @MessageBoxA
      26. ENDASM
      27. Print MsgBox(%hWnd)
      28. waitinput
      Alles anzeigen
      (Intel Duo E8400 3,0 GHz / 4 GB RAM / 250 GB HDD / ATI Radeon HD4770 512 MB / Windows Vista - ausgemustert zum Verkauf)
      AMD Athlon II X2 2,9 GHz / 8 GB RAM / 500 + 1000 GB HDD / ATI Radeon 3000 (onboard) / Windows 10(64) - XProfan X4


      http://www.xprofan.de
    • Ok, dann hilft folgender Kunstgriff:

      Quellcode

      1. Windowstyle 24:Window 800,600
      2. var errorlevel&=set("Errorlevel",-1):get("ASMMODE")
      3. var error%=%error:errorlevel&=set("Errorlevel",errorlevel&)
      4. if error%=0
      5. var hDLL&=UseDLL("USER32.DLL"):ImportFunc(hDLL&,"MessageBoxA",""):set("ASMMODE",0)
      6. ASM "MsgBox",1:JMP Start:Typ::DD 51:Titel::DS "Wichtige Meldung!\z":Text:
      7. DS "Das ist der Hinweis!\z":Start::MOV EAX,[Typ]:PUSH EAX:MOV EAX,Titel
      8. PUSH EAX:MOV EAX,Text:PUSH EAX:MOV EAX,Par1:PUSH EAX:CALL @MessageBoxA:ENDASM
      9. Print MsgBox(%hWnd)
      10. else
      11. Print " Funktion ASM steht nicht zur Verfügung! Ergebnis herkömmlich zu programmieren!"
      12. endif
      13. waitinput 1e5
      14. end
      Alles anzeigen
    • In der fertigen Version kannst Du ja einfach die Version abfragen ($ProfVer), bzw. die bedingte Kompilierung nutzen ($IFDEF VER14.0). Momentan sind die entsprechenden Werte noch nicht angepasst.

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


      http://www.xprofan.de
    • Selbstverständlich wird ASM auch mit Compiler und Runtime funktionieren (bei mir tut es das schon). Die einzig sichere Abfrage wird in der fertigen Version über die Versionsnummer gehen. Und für die jetzige Alpha-Version ist es sowieso unerheblich.

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


      http://www.xprofan.de
    • Der Assembler bringt ja wunderbare Fehlermeldungen. Allerdings nicht, wenn ein Label nicht vorhanden ist. Das kann dann zu unliebsamen Überraschungen führen.

      Quellcode

      1. ASM "Test", 1
      2. mov eax, par1
      3. cmp eax, 4
      4. je @@gleich
      5. add eax, 4
      6. EndASM
      7. cls
      8. print "Starte Aufruf"
      9. print Test(4)
      10. waitinput
      Alles anzeigen



      Gruß Volkmar
    • Oh, da muss ich mal schauen. Auch da sollte es eine Fehlermeldung geben.

      BTW: Am Wochenende hatte ich eine neue Version mit Bugfixes* hochgeladen, die sich außerdem als Version X4ß zu erkennen gibt.

      Gruß
      Roland

      *In einigen Fällen wurden falsche Codes erzeugt, wenn es sich um 8-Bit-Register (AH, AL, etc.) als ersten Parameter handelte.

      PS: Die nächste Version wird das Daten-Austausch-Format JSON unterstützen.
      (Intel Duo E8400 3,0 GHz / 4 GB RAM / 250 GB HDD / ATI Radeon HD4770 512 MB / Windows Vista - ausgemustert zum Verkauf)
      AMD Athlon II X2 2,9 GHz / 8 GB RAM / 500 + 1000 GB HDD / ATI Radeon 3000 (onboard) / Windows 10(64) - XProfan X4


      http://www.xprofan.de
    • Neue Version hochgeladen! Neben der Fehlermeldung bei fehlendem Label gibt es jetzt auch eine Unterstützung des JSON-Formates.

      Gruß
      Roland

      Ach ja:

      Frohe Ostern!
      (Intel Duo E8400 3,0 GHz / 4 GB RAM / 250 GB HDD / ATI Radeon HD4770 512 MB / Windows Vista - ausgemustert zum Verkauf)
      AMD Athlon II X2 2,9 GHz / 8 GB RAM / 500 + 1000 GB HDD / ATI Radeon 3000 (onboard) / Windows 10(64) - XProfan X4


      http://www.xprofan.de
    • Hallo Roland,
      Hast du mit den Labels noch was geändert ?

      Man muß jetzt mit den Quellcodes, die am Anfang
      hier gepostet wurden, aufpassen :

      @Schleife: -> erzeugt jetzt eine Fehlermeldung (Funktion unbekannt)

      geht jetzt nur noch ohne @ oder halt mit zwei @@.

      Nur mal so als Hinweis für andere User.
    • Wie hier bereits beschrieben, steht das einfache @ jetzt für eine Funktions-Adresse. Mit "Call @funk" wird eine Funktion an der Adresse funk aufgerufen. (Das macht das zeitweise vorhandene Makro FCALL überflüssig.)

      Für Labels benötigt man in XProfan überhaupt keine "@@". Die kommen in der Regel bei übernommenen Codes aus anderen Programmiersprachen vor. Man findet sie zum Beispiel beim Delphi-Inline-Assembler. (Auch in Delphi steht das einfache @ für eine Adresse.)

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


      http://www.xprofan.de
    • Danke,
      war oben nicht so ganz ersichtlich.
      Aber ich hätte ja auch logischerweise darauf schließen
      müssen :
      Wenn es für Call gebraucht wird, kann es natürlich
      nicht mehr für ein Label verwendet werden.

      Ich lasse die Dinger (@@) auch lieber weg.

      PS: Lass den ASMMODE so, wie er ist.
      Für kleine Minicodes ist Modus 2 ja ganz brauchbar.

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

    • Schlage in weiteren Ausbaustufen von RGH-XASM die Aufnahme der FPU-Befehle vor.
      Floating Point-Arithmetik eröffnet dann sicher wichtige weitere Anwendungsfelder für XProfan.

      Gruss und FROHE OSTERN!

      P.S.: OpCode-Liste, exzerpiert aus den aktuellen Intel-Handbüchern.
      Spoiler anzeigen

      // 80x86/87 FPU INSTRUCTION SET
      // ============================
      D9 F0 F2XM1
      D9 E1 FABS
      D8 /0 FADD m32fp
      DC /0 FADD m64fp
      D8 C0+i FADD ST(0), ST(i)
      DC C0+i FADD ST(i), ST(0)
      DE C0+i FADDP ST(i), ST(0)
      DE C1 FADDP
      DA /0 FIADD m32int
      DE /0 FIADD m16int
      DF /4 FBLD m80dec
      DF /6 FBSTP m80bcd
      D9 E0 FCHS
      9B DB E2 FCLEX
      DB E2 FNCLEX
      DA C0+i FCMOVB ST(0), ST(i)
      DA C8+i FCMOVE ST(0), ST(i)
      DA D0+i FCMOVBE ST(0), ST(i)
      DA D8+i FCMOVU ST(0), ST(i)
      DB C0+i FCMOVNB ST(0), ST(i)
      DB C8+i FCMOVNE ST(0), ST(i)
      DB D0+i FCMOVNBE ST(0), ST(i)
      DB D8+i FCMOVNU ST(0), ST(i) //avaliable if CPUID´s CMOV and FPU feature bits are set
      D8 /2 FCOM m32fp
      DC /2 FCOM m64fp
      D8 D0+i FCOM ST(i)
      D8 D1 FCOM
      D8 /3 FCOMP m32fp
      DC /3 FCOMP m64fp
      D8 D8+i FCOMP ST(i)
      D8 D9 FCOMP
      DE D9 FCOMPP
      DB F0+i FCOMI ST, ST(i)
      DF F0+i FCOMIP ST, ST(i)
      DB E8+i FUCOMI ST, ST(i)
      DF E8+i FUCOMIP ST, ST(i)
      D9 FF FCOS
      D9 F6 FDECSTP
      D8 /6 FDIV m32fp
      DC /6 FDIV m64fp
      D8 F0+i FDIV ST(0), ST(i)
      DC F8+i FDIV ST(i), ST(0)
      DE F8+i FDIVP ST(i), ST(0)
      DE F9 FDIVP
      DA /6 FIDIV m32int
      DE /6 FIDIV m16int
      D8 /7 FDIVR m32fp
      DC /7 FDIVR m64fp
      D8 F8+i FDIVR ST(0), ST(i)
      DC F0+i FDIVR ST(i), ST(0)
      DE F0+i FDIVRP ST(i), ST(0)
      DE F1 FDIVRP
      DA /7 FIDIVR m32int
      DE /7 FIDIVR m16int
      DD C0+i FFREE ST(i)
      DE /2 FICOM m16int
      DA /2 FICOM m32int
      DE /3 FICOMP m16int
      DA /3 FICOMP m32int
      DF /0 FILD m16int
      DB /0 FILD m32int
      DF /5 FILD m64int
      D9 F7 FINCSTP
      9B DB E3 FINIT
      DB E3 FNINIT
      DF /2 FIST m16int
      DB /2 FIST m32int
      DF /3 FISTP m16int
      DB /3 FISTP m32int
      DF /7 FISTP m64int
      DF /1 FISTTP m16int
      DB /1 FISTTP m32int
      DD /1 FISTTP m64int
      D9 /0 FLD m32fp
      DD /0 FLD m64fp
      DB /5 FLD m80fp
      D9 C0+i FLD ST(i) // pushing register ST(0) duplicates the stack top.
      D9 E8 FLD1
      D9 E9 FLDL2T
      D9 EA FLDL2E
      D9 EB FLDPI
      D9 EC FLDLG2
      D9 ED FLDLN2
      D9 EE FLDZ
      D9 /5 FLDCW m2byte // Loads the 16-bit source operand into the FPU control word. To avoid raising exceptions clear any pending exceptions
      D9 /4 FLDENV m14/28byte
      D8 /1 FMUL m32fp
      DC /1 FMUL m64fp
      D8 C8+i FMUL ST(0), ST(i)
      DC C8+i FMUL ST(i), ST(0)
      DE C8+i FMULP ST(i), ST(0)
      DE C9 FMULP
      DA /1 FIMUL m32int
      DE /1 FIMUL m16int
      D9 D0 FNOP
      D9 F3 FPATAN
      D9 F8 FPREM
      D9 F5 FPREM1
      D9 F2 FPTAN
      D9 FC FRNDINT
      DD /4 FRSTOR m94/108byte
      9B DD /6 FSAVE m94/108byte
      DD /6 FNSAVE m94/108byte
      D9 FD FSCALE
      D9 FE FSIN
      D9 FB FSINCOS
      D9 FA FSQRT
      D9 /2 FST m32fp
      DD /2 FST m64fp
      DD D0+i FST ST(i)
      D9 /3 FSTP m32fp
      DD /3 FSTP m64fp
      DB /7 FSTP m80fp
      DD D8+i FSTP ST(i)
      9B D9 /7 FSTCW m2byte
      D9 /7 FNSTCW m2byte
      9B D9 /6 FSTENV m14/28byte
      D9 /6 FNSTENV m14/28byte
      9B DD /7 FSTSW m2byte
      9B DF E0 FSTSW AX
      DD /7 FNSTSW * m2byte
      DF E0 FNSTSW * AX
      D8 /4 FSUB m32fp
      DC /4 FSUB m64fp
      D8 E0+i FSUB ST(0), ST(i)
      DC E8+i FSUB ST(i), ST(0)
      DE E8+i FSUBP ST(i), ST(0)
      DE E9 FSUBP
      DA /4 FISUB m32int
      DE /4 FISUB m16int
      D8 /5 FSUBR m32fp
      DC /5 FSUBR m64fp
      D8 E8+i FSUBR ST(0), ST(i)
      DC E0+i FSUBR ST(i), ST(0)
      DE E0+i FSUBRP ST(i), ST(0)
      DE E1 FSUBRP
      DA /5 FISUBR m32int
      DE /5 FISUBR m16int
      D9 E4 FTST
      DD E0+i FUCOM ST(i)
      DD E1 FUCOM
      DD E8+i FUCOMP ST(i)
      DD E9 FUCOMP
      DA E9 FUCOMPP
      D9 E5 FXAM
      D9 C8+i FXCH ST(i)
      D9 C9 FXCH //FXCH ST(3);FSQRT;FXCH ST(3);
      D9 F4 FXTRACT
      D9 F1 FYL2X
      D9 F9 FYL2XP1
      // NP 0F AE /1 FXRSTOR m512byte
      // NP REX.W + 0F AE /1 FXRSTOR64 m512byte
      // NP 0F AE /0 FXSAVE m512byte
      // NP REX.W + 0F AE /0 FXSAVE64 m512byte //Bytes 464:511 are available to software use.
      // Op/En Operand_1 Operand_2 Operand_3 Operand_4
      // M ModRM:r/m (r\w) NA NA NA
    • Neue Version hochgeladen.

      Im Zusammenhang mit den neuen FPU-Befehlen sind folgende neue CPU-Befehle sinnvoll:

      FWAIT, SAHF und LAHF.

      Und das Wichtigste: Die wichtigsten FPU-Befehle werden jetzt auch unterstützt:

      FLD, FST und FSTP haben als Parameter entweder ein Register oder eine Adresse in eckigen Klammern in den bekannten Spielarten. Wichtigster Unterschied: Die FPU kann natürlich nicht auf die CPU-Register zugreifen, sondern nutzt die 8 FPU-Register ST0 bis ST7, die als Stapel verwendet werden. ST0 ist der oberste Wert. (Eine andere gebräuchliche Schreibweise für die Register ist ST(0) bis ST(7), wober statt ST(0) auch nur ST geschrieben werden kann. XProfan unterstützt auch diese Schreibweise.)

      Mit FLD wird ein Fließkommawert von der angegebenen Adresse auf den Stapel gelegt. Was zuvor auf dem obersten Platz (ST0) lag, rutscht damit auf ST1, etc. Wichtig: Wenn alle 8 Stapelplätze belegt sind kann man keinen neuen Wert hinzufügen. Beim Versuch gibt es einen Fehler und der oberste Wert ist undefiniert.
      Beim Verlassen der Routine muss der Stapel sich im gleichen Zustand wie zu Beginn befinden, sonst gibt es die seltsamsten Fehler. Also alles was draufgepackt wird, muss auch wieder heruntergenommen werden. (Oder man räumt am Ende mit FINIT auf. Diese Notlösung ist aber nicht zu empfehlen.)
      Tipp: Mit FLD ST0 kopiert man den obersten Wert und legt ihn erneut aufen Stapel, so dass er dirt dann zweimal ist: in ST0 und ST1.

      Mit FST wird der oberste Wert an die im Parameter angegebene Adresse geschrieben. FSTP macht das gleiche, aber entfernt den Wert dann vom Stapel (Das "P" steht für POP).

      Folgende Befehle legen feste Werte auf den Stapel:
      FLD1: 1.0
      FLDZ: 0.0
      FLDPI: Pi
      FLDL2E: log2 e
      FLDL2T: log2 10
      FLDLG2: log10 2
      FLDLN2: loge 2

      Mit FSTSW kopiert man das 16 Bit breite Status-Register der FPU nach AX (die untersten 16 Bit von EAX). Mit SAHF kann man die oberen 8 Bit mit den Flags in das Flag-Register der CPU laden, um die Flags dann z.B. für Sprünge auszuwerten. (Eine andere Schreibweise für diesen Befehl ist FSTSW AX.)

      Weiter geht es im Laufe des Wochenendes mit den Rechenbefehlen und Beispielen im nächsten Beitrag!

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


      http://www.xprofan.de