ALGORITHMEN TEIL XII: Cogito errare est

    Wir verlosen 4 x das Buch Windows 10 - Schritt für Schritt erklärt Schau gleich mal rein!

    • Neu

      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 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 1 mal editiert, zuletzt von RGH ()

    • Neu

      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
    • Neu

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

    • Neu

      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 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
    • Neu

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

    • Neu

      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 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
    • Neu

      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 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
    • Neu

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