@funkheld: Dann würde ich noch mal zur Anmerkung von __deets__ zurück wollen, dass es bessere Sprachen/Umgebungen gibt um sich mit Assembler zu beschäftigen als ausgerechnet Python und da dann auch noch irgendwelche Byte-Blobs selbst in den Speicher zu laden und ausführbar zu machen. Da würde ich ja mindestens mal „shared libraries“, also unter Windows DLLs als Ziel nehmen, weil die sich einfacher in Python, aber auch in andere Programmiersprachen integrieren lassen, und damit dieses Problem und diese Fehlerquelle schon mal weg fällt.
Am einfachsten wäre C und Assembler, weil C im Grunde so etwas wie ein portabler Makroassembler ist, die Schritt von C-Quelltext zu Assembler in der Regel recht offensichtlich und direkt ist (solange man den Compiler keine Optimierungen machen lässt ), und man so auch erst einmal ein bisschen Prototyping in C betreiben kann, bevor man etwas in handgeschriebenen Assembler umsetzt. Mit C muss man sich sowieso bis zu einem gewissen Grad auseinandersetzen, weil die Schnittstellen in der Regel aus Sicht von C-Programmierern ge-/beschrieben sind. So ja auch das `ctypes`-Modul in Python und APIs von DLLs, egal in welcher Programmiersprache die letztlich geschrieben sind. (Wobei ich hier von ”echten” DLLs ausgehe, also welche die nativen Maschinencode enthalten und keinen .NET-Bytecode.)
Und ich würde mich auch erst einmal über ”PC-Assembler” informieren, denn das sind im Grunde drei Sprachen, angefangen mit 16-Bit-Assembler, über 32-Bit-Assembler, bis zu 64-Bit-Assembler. Die Frage nach dem konkreten Buch hattest Du nicht beantwortet, aber ein Buch über 16-Bit-Assembler in einer DOS-Umgebung wird bei 32-Bit oder 64-Bit-Windowsanwendungen nicht so wirklich weiterhelfen. Bei so einem Buch wäre Python sowieso raus, weil man da mit DOS arbeiten müsste/würde. Entweder mit einem echten (Retro-)Rechner, oder in einer virtuellen Umgebung, die so etwas emuliert. VirtualPC, Qemu, Dosbox, … da gibt es ja einiges.
Python mit ASM funktioniert nicht.
- __blackjack__
- User
- Beiträge: 13533
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Code: Alles auswählen
- (void)countSheep {
unsigned int sheep = 0;
while ( ! [self isAsleep]) { ++sheep; }
}
Das hast du ja schon öfter geschrieben. Was genau meinst du mit Makro-Assembler? Dass es ein erweiterter Assembler ist (also mit mehr Funktionalität)? Oder dass alle Funktionen aus der C-Standardbibliothek wie Makros sind? Oder vielleicht auch beides? Würde mich mit meinen rudimentären C-Kenntnissen wirklich mal interessieren...__blackjack__ hat geschrieben: ↑Dienstag 24. Januar 2023, 12:55 (...) weil C im Grunde so etwas wie ein portabler Makroassembler ist (...)
EDIT: Oder bezieht sich das nur auf den Compiler ohne die Stdlib? Also dass der eine Codezeile relativ transparent in Assemblercode übersetzt? Ich vermute, das meintest du tatsächlich, oder?
Zuletzt geändert von snafu am Dienstag 24. Januar 2023, 19:46, insgesamt 1-mal geändert.
Das ist ein bisschen despektierlich ausgedrueckt, dass C eine sehr primitive Sprache mit wenig Abstraktionen ist. Ich wuerde das jetzt so nicht unterschreiben, schon alleine Dinge wie Strukturen und Calling-Conventions sind ein grosser Schritt nach vorne.
@__deets__:
Kommt vielleicht auf die Vorkenntnisse in Assembler an. Hier wird z.B. der "offensichtliche" Code zum Befüllen eines Structs gezeigt:
https://diveintosystems.org/book/C7-x86_64/structs.html
Kommt vielleicht auf die Vorkenntnisse in Assembler an. Hier wird z.B. der "offensichtliche" Code zum Befüllen eines Structs gezeigt:
https://diveintosystems.org/book/C7-x86_64/structs.html
Da jedweder Code, der auf einem Rechner ausgefuehrt wird, immer Maschinensprache ist, folgt trivial, dass jedwedes befuellen eines Speicherbereichs mit Daten irgendwie auf eine Folge von Assembler-Instruktionen abbildbar ist. Das ist nicht der Punkt. Der Punkt ist, dass es dafuer keine Abstraktionen gibt *in* Assembler. Sonder man jeden Zugriff von Hand schreibt. Mit einem Macro-Assembler kann man sich das etwas leichter machen, aber auch das hat enge Grenzen. Wenn man dann anfaengt, Code zu generieren, ist man schon beim eigenen Compiler angekommen.
- __blackjack__
- User
- Beiträge: 13533
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@snafu: Makroassembler übersetzen nicht nur stumpf Labels, Namen, und Mnenonics für Maschinenbefehle in Zahlen, sondern erlauben auch Makros zu definieren, mit Argumenten, Abfragen, Schleifen, Verzweigungen zur Laufzeit. Einige sind da ziemlich flexibel so dass man sich da schon fast kleine Programmiersprachen mit basteln kann, die nahe an so etwas ”primitives” wie C heran kommen, womit C umgekehrt dann nicht mehr so weit von so einem Makroassembler entfernt ist.
@__deets__: Aufrufkonventionen und Strukturen werden von einigen Makro-Assemblern auch unterstützt. In MASM kann man Prozeduren definieren (oder externe deklarieren), mit Aufrufkonvention (C, STDCALL, …) und Argumenten. Der Assembler generiert Code für den nötigen Stackrahmen und für die Zugriffe per Namen auf die Argumente und lokale Namen und es gibt INVOKE das für das ablegen der Argumente in der richtigen Reihenfolge auf dem Stack sorgt. Strukturen kann man auch definieren. Es ist noch nicht ganz C, aber man kann sich da schon recht viel Boilerplate-Code automagisch generieren lassen.
@__deets__: Aufrufkonventionen und Strukturen werden von einigen Makro-Assemblern auch unterstützt. In MASM kann man Prozeduren definieren (oder externe deklarieren), mit Aufrufkonvention (C, STDCALL, …) und Argumenten. Der Assembler generiert Code für den nötigen Stackrahmen und für die Zugriffe per Namen auf die Argumente und lokale Namen und es gibt INVOKE das für das ablegen der Argumente in der richtigen Reihenfolge auf dem Stack sorgt. Strukturen kann man auch definieren. Es ist noch nicht ganz C, aber man kann sich da schon recht viel Boilerplate-Code automagisch generieren lassen.
Code: Alles auswählen
- (void)countSheep {
unsigned int sheep = 0;
while ( ! [self isAsleep]) { ++sheep; }
}
OK, das die so weit gehen, war mir nicht bewusst. Wobei dann der Vergleich auch ein bisschen unfair ist, weil man natuerlich im Grunde einen Code-Generator gebaut hat, also vulgo Compiler. Da werden die Uebergaenge dann natuerlich fliessend. Ein Macro-Assembler ist dann naeher an C, als an Assembler
Das scheint mir insbesondere beim MASM von Microsoft eher ein Hybrid aus beiden "Welten" zu sein. Also so ein bisschen wie Cython (übertragen auf Assembler). Finde ich nach anfänglicher Überraschung über die Abstraktion gar nicht mal so schlecht. An sich ist das schon ne eigene Sprache, aber halt nicht unbedingt von Assembler entfernt, vielmehr eine Erweiterung.
- __blackjack__
- User
- Beiträge: 13533
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@__deets__: Ich mochte MASM deswegen auch nie so wirklich, weil da zu viel Magie passiert und manchmal wirklich überraschende Dinge passieren. Das beispielsweise NASM diesen ganzen Zauber nicht macht ist mir sehr sympathisch. Getreu dem Python Zen „Explicit is better than implicit.“
@snafu Wobei MASM ja der Massstab für DOS/Windows ist, da die Konkurrenten in der Regel Klone sind, die versuchen ein bisschen besser zu sein. Also beispielsweise TASM mit seinem Ideal-Modus und mehr Typprüfung. Weil mir das alles zu kompliziert war, vom C64 und eher einfachen Assemblern kommend, hatte ich mich unter DOS hauptsächlich auf den Inline-Assembler in Turbo-/Borland-Pascal beschränkt. Das fand ich verdaulicher, weil die ”Magie” dort Pascal-Syntax war, statt das man noch irgendeine zusätzliche Makrosprache und Direktiven von einem Assembler lernen musste.
@snafu Wobei MASM ja der Massstab für DOS/Windows ist, da die Konkurrenten in der Regel Klone sind, die versuchen ein bisschen besser zu sein. Also beispielsweise TASM mit seinem Ideal-Modus und mehr Typprüfung. Weil mir das alles zu kompliziert war, vom C64 und eher einfachen Assemblern kommend, hatte ich mich unter DOS hauptsächlich auf den Inline-Assembler in Turbo-/Borland-Pascal beschränkt. Das fand ich verdaulicher, weil die ”Magie” dort Pascal-Syntax war, statt das man noch irgendeine zusätzliche Makrosprache und Direktiven von einem Assembler lernen musste.
Code: Alles auswählen
- (void)countSheep {
unsigned int sheep = 0;
while ( ! [self isAsleep]) { ++sheep; }
}
Mit dem Buch hast du recht , es passt nicht in mein Gebiet was ich machen möchte.
Ich habe schon DLL entworfen mit dem Freebasic. Funktioniert auch gut.
Natürlich ist der Weg bis zur Nutzung in Python länger.
Ich habe dann auf meinen PC das Python laufen und das Freebasic und kann durch meine entworfenen Programme im Batch beide schnell füttern.
Funktinoniert auch wunderbar.
Das Purebasic ist gebunden mit der freigebe der DLL.
Ich habe schon DLL entworfen mit dem Freebasic. Funktioniert auch gut.
Natürlich ist der Weg bis zur Nutzung in Python länger.
Ich habe dann auf meinen PC das Python laufen und das Freebasic und kann durch meine entworfenen Programme im Batch beide schnell füttern.
Funktinoniert auch wunderbar.
Das Purebasic ist gebunden mit der freigebe der DLL.
- __blackjack__
- User
- Beiträge: 13533
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@funkheld: Was denn jetzt? FreeBASIC oder PureBasic? Und wozu brauchst Du da jetzt genau Assembler? Beide Compiler können DLLs erzeugen, die kann man mit `ctypes` einbinden. Beispiel für FreeBASIC (unter Linux):
Übersetzt mit:
Kann man von Python aus so benutzen:
Kein Assembler notwendig. Mal von Dateinamenskonventionen (.so vs. .dll) abgesehen, auch portabel zwischen Systemen und 32 vs. 64 Bit, solange man entsprechend 32- oder 64-Bit-Code mit dem BASIC-Compiler erzeugt.
Code: Alles auswählen
FUNCTION f ALIAS "f" (n AS Integer) As Integer EXPORT
RETURN n + 5
END FUNCTION
Code: Alles auswählen
fbc -dll test_fb.bas
Code: Alles auswählen
#!/usr/bin/env python3
import ctypes
LIB = ctypes.CDLL("./libtest_fb.so")
f = LIB.f
f.argtypes = [ctypes.c_int]
f.restype = ctypes.c_int
def main():
print(f(42))
if __name__ == "__main__":
main()
Code: Alles auswählen
- (void)countSheep {
unsigned int sheep = 0;
while ( ! [self isAsleep]) { ++sheep; }
}
- __blackjack__
- User
- Beiträge: 13533
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@funkheld: Welches ASM? Oder ist das gar nicht BASIC sondern Du verwendest das nur um manuell geschriebenen Assembler in eine DLL zu bekommen? Um die dann in Python zu laden‽ Weil das einfacher ist als was? Gleich eine DLL aus dem Assembler zu bauen, ohne da *noch* eine Programmiersprache in den sowieso schon sehr fragwürdigen Mix zu werfen? Das kann es ja eher nicht sein.
Falls das Ziel ist Assembler zu lernen, dann ist Python als Sprache zum einbetten nicht wirklich geeignet, weil unnötige Hürden aufgebaut werden und überwunden werden müssen, die nicht wirklich etwas mit Assembler lernen zu tun haben. Auf aktueller Hardware bietet sich C an, weil die ganzen Schnittstellen wie beispielsweise DLLs auf C ausgelegt sind, und es Werkzeuge wie IDEs und Debugger gibt, die sowohl auf C- als auch auf Assemblerebene operieren können.
Falls das Ziel ist Assembler zu lernen, dann ist Python als Sprache zum einbetten nicht wirklich geeignet, weil unnötige Hürden aufgebaut werden und überwunden werden müssen, die nicht wirklich etwas mit Assembler lernen zu tun haben. Auf aktueller Hardware bietet sich C an, weil die ganzen Schnittstellen wie beispielsweise DLLs auf C ausgelegt sind, und es Werkzeuge wie IDEs und Debugger gibt, die sowohl auf C- als auch auf Assemblerebene operieren können.
Code: Alles auswählen
- (void)countSheep {
unsigned int sheep = 0;
while ( ! [self isAsleep]) { ++sheep; }
}
Nicht, dass das nicht schon erwaehnt worden waere... mal ein bisschen weiter auszuholen, was da eigentlich warum wie geplant ist, wuerde den Beteiligten hier das Leben leichter machen, statt auf mehreren Seiten um den heissen Brei zu eiern.