Nur mal theoretisch: Kann man die Adresse von Sprungmarken auslesen, um sie in einer Sprungtabelle zu speichern? Und natürlich wird das passende Gegenstück benötigt, ein indirekter Jump-Befehl, der eine Adresse in einer Sprungtabelle ansteuern kann (Goto will ich das nicht nennen, ich fürchte Schläge ;-) ) Das ist ja nur theoretisch, eine Art "on <Ausdruck> goto <Sprungmarke>". Ich vermute, ohne Asm-Einbindung ist das in C nicht realisierbar, oder? Es ist wirklich nur theoretisch. Niemand will eine Mauer bauen :D Wer doch den Zeigefinger heben muss, weil er nicht anders kann, bedenke: switch ist auch nicht mehr als ein ausdruckgesteuertes GOTO
Frotho schrieb: > Nur mal theoretisch: > > Kann man die Adresse von Sprungmarken auslesen Ja aus dem MAP File welches vom Linker erzeugt wird. , um sie in einer > Sprungtabelle zu speichern? Und natürlich wird das passende Gegenstück > benötigt, ein indirekter Jump-Befehl, der eine Adresse in einer > Sprungtabelle ansteuern kann (Goto will ich das nicht nennen, ich > fürchte Schläge ;-) ) Warum willst du unbedingt zu bestimmten Adressen springen? Wenn du dynamisch "springen" willst, nimm Funktionspointer. Die kannst du in Arrays und Structs verwalten wie du lustig bist. > Das ist ja nur theoretisch, eine Art "on <Ausdruck> goto <Sprungmarke>". > Ich vermute, ohne Asm-Einbindung ist das in C nicht realisierbar, oder? Du kannst auch in C direkt zu jeder Adresse springen. Nimmt man z.B. für Sprünge in den Bootloader. > > Es ist wirklich nur theoretisch. Niemand will eine Mauer bauen :D
:
Bearbeitet durch User
Cyblord -. schrieb: > Warum willst du unbedingt Will ich doch gar nicht Frotho schrieb: > Niemand will eine Mauer bauen :D > Wenn du dynamisch "springen" willst, nimm Funktionspointer. Funktionspointer sind doch Pointer auf Funktionen. Das ist ganz was anderes als ein Label innerhalb einer Funktion. Wer immer nur mit der Herde blökt "goto ist pfui", wird auch immer nur in seinem (Denk)Gatter bleiben. Jedem das seine. Ein sinnvoller Einsatz von Goto (außer in absoluten Ausnahmefällen wie bei Fehlern) fällt mir gerade auch nicht ein (nicht mal in BASIC). Pfui ist es deswegen noch lange nicht. Gosub habe ich z.B. gerne verwendet. Für Routinen, die an mehreren Stellen innerhalb einer Funktion dasselbe tun, war Gosub ideal, um die Anzahl von Sonderfunktionen (Funtions-Unterfunktionen) zu reduzieren. Außerdem, wenn die Routine viele Parameter hat, die lokal innerhalb der Funktion zur Verfügung stehen, warum soll man die an eine Unterfunktion übergeben müssen, wenn es auch einfacher geht? Hat ja auch was mit Übersicht in komplexen Programmen zu tun. Nur mal so zur Theorie. Und daraus entsteht eben KEIN Spaghetticode (manche Leute kriegen Spaghetticode übrigens auch mit üblichen Mitteln hin...).
Frotho schrieb: >> Wenn du dynamisch "springen" willst, nimm Funktionspointer. > Funktionspointer sind doch Pointer auf Funktionen. Das ist ganz was > anderes als ein Label innerhalb einer Funktion. Dein Anspruch war, Sprunkmarken in einer Tabelle zu verwalten. Das geht mit Funktionspointern sehr gut. Dazu brauchts kein Goto. Und warum will man INNERHALB einer Funktion springen? Dafür gibts, wie du schon gemerkt hast, Switch. > > Wer immer nur mit der Herde blökt "goto ist pfui", wird auch immer nur > in seinem (Denk)Gatter bleiben. Jedem das seine. Ein sinnvoller Einsatz > von Goto (außer in absoluten Ausnahmefällen wie bei Fehlern) fällt mir > gerade auch nicht ein (nicht mal in BASIC). Pfui ist es deswegen noch > lange nicht. Du willst anscheinend nur wegen Goto rumpöbeln. Niemand hat hier Goto als Pfui bezeichnet. Dass man es nicht einfach hernehmen sollte um Wild im Programm zu springen ist heute fast jedem klar. Nur dein Szenario, nämlich Sprungmarken in Tabellen zu halten erfüllt es auch nicht. > Will ich doch gar nicht Dann überleg dir was du willst. Für allgemeines sinnfreies gelabere über goto und blöken stehe ich nicht zur Verfügung.
Cyblord -. schrieb: > Du kannst auch in C direkt zu jeder Adresse springen. Nimmt man z.B. für > Sprünge in den Bootloader. Mit welchem Komando denn? Ein Funktionspointer speichert doch die Rücksprungadresse im Stack. Kommt also nicht in Frage,wenn man das RET des Bootloaders nutzen will. Also Goto. Aber das kann keine Adressen. Oder eine Art "ASM jump" ? Weiß gerade nicht genau, was du meinst ...
Frotho schrieb: > Kann man die Adresse von Sprungmarken auslesen, um sie in einer > Sprungtabelle zu speichern? GCC kann sowas als Erweiterung: https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html#Labels-as-Values Mir ist aber in knapp 30 Jahren C-Praxis noch nichts untergekommen, wo ich sowas als vorteilhaft erachtet hätte. ;-)
Cyblord -. schrieb: > Dann überleg dir was du willst. Für allgemeines sinnfreies gelabere über > goto und blöken stehe ich nicht zur Verfügung. Ich auch nicht. Aber google nach Goto, und man weiß, was einem blüht. Das will ich vermeiden. Was ich will, habe ich geschrieben.
Jörg W. schrieb: > Mir ist aber in knapp 30 Jahren C-Praxis noch nichts untergekommen, wo > ich sowas als vorteilhaft erachtet hätte. ;-) Danke. Ich habe noch keine 30 Jahren C, aber bei mir wird das goto kein Standard werden. Hätte ja schon mal irgendwann ein Fall auftreten müssen, ist aber nicht. Gewisse Dinge mögen selten sein. Aber es gibt Fälle, wo "seltsame Methoden" eine gute Lösung sind.
Jörg W. schrieb:
...
Ja, ist genau das, was ich gesucht habe :-)
Über Labeladresse + Labelvariable findet sich bei Google fast nichts.
Labeladressen lassen sich mit && auslesen, in einem void * ptr;
speichern und mit goto * ptr; aufrufen. Nur wer es mal braucht.
Als Sinn fällt mir ein Prozess-Dispatcher ein. Vielleicht werde ich die
Modul-Sourcen i.d. ISR, die aktuell noch sequentiell ablaufen, via
Jumptable in Prozesse aufteilen. Mal sehen.
Danke jedenfalls.
Frotho schrieb: > Als Sinn fällt mir ein Prozess-Dispatcher ein. Sowas sollte man aber in der Tat auch mit Funktionszeigern machen können, und die sind halt C-Standard.
Frotho schrieb: > Cyblord -. schrieb: > >> Du kannst auch in C direkt zu jeder Adresse springen. Nimmt man z.B. für >> Sprünge in den Bootloader. > > Mit welchem Komando denn? Ein Funktionspointer speichert doch die > Rücksprungadresse im Stack. Na und? Man springt halt nie zurück. Ist beim Bootloader meistens egal.
Jörg W. schrieb: > Frotho schrieb: >> Als Sinn fällt mir ein Prozess-Dispatcher ein. > > Sowas sollte man aber in der Tat auch mit Funktionszeigern machen > können, und die sind halt C-Standard. Ja natürlich kann man das. Es ist aber ein Unterschied, ob ich die eine Funkion (ISR) in 9 Funktionen auslagere, mitsamt dem Overhead Parameterübergabe & Co, oder ob die Bearbeitung in der Kapsel bleibt. Vielleicht ist das auch Geschmacksache. Ich versuche, die Anzahl Funktionen niedrig zu halten. Liegt vlt. auch daran, dass ich mich ewig quäle mit der Namensgebung. Egal warum, ein "jump[index]" ziehe ich bei zeitkritischen Routinen dem "normalen" Aufruf über Funktionszeigerarray vor. Wir o.g., gibts auch durch Paramter und Results Overhead, was i.d. ISr nicht sein muss, finde ich jedenfalls.
Frotho schrieb: > Ja natürlich kann man das. Es ist aber ein Unterschied, ob ich die eine > Funkion (ISR) in 9 Funktionen auslagere, mitsamt dem Overhead > Parameterübergabe & Co, oder ob die Bearbeitung in der Kapsel bleibt. Du solltest dich von Vorstellungen lösen, die offensichtlich von Maschinen mit akutem Registermangel wie einem alten x86 herrühren. Auf vernünftigen Maschinen kostet eine Parameterübergabe in eine Funktion rein gar nichts, da sie in Registern abgehandelt wird. Ob überhaupt Stack dafür benötigt wird, ist auch bei einer Funktion nicht völlig klar. Wichtig ist es in C, den Scope der Funktionen klein zu halten (static), damit der Compiler weiß, dass sie wirklich nur an dieser Stelle gebraucht werden. U. U. kann er dann auch alles inline erweitern und die Funktionsaufrufe komplett eliminieren.
Jörg W. schrieb: > Du solltest dich von Vorstellungen lösen, die offensichtlich von > Maschinen mit akutem Registermangel wie einem alten x86 herrühren. Auf > vernünftigen Maschinen kostet eine Parameterübergabe in eine Funktion > rein gar nichts, da sie in Registern abgehandelt wird. Ob überhaupt > Stack dafür benötigt wird, ist auch bei einer Funktion nicht völlig > klar Beim TE mangelt es offensichtlich nicht an Speicher sondern an kognitiven Möglichkeiten Programme sinnvoll zu strukurieren. Ich kenne ja die Diskussion mit OOP-Gegnern. Aber jemanden der sogar strukurierte Programmierung mittels Funktionen ablehnt, ist mir schon lange nicht mehr untergekommen.
Jörg W. schrieb: > Du solltest dich von Vorstellungen lösen Ja kann sein. Ich habe mal Interpreter geschrieben und davor TSRs. x86 stimmt genau, sogar noch 286 + 386, einen Z80 Interpreter als Vorbild. Die Z80 Sourcen habe ich noch im Kopf. Das absolute Paradies, aber eben Overhead. Bei C kenne ich die interen Strukturen nicht. Ich vermute aber mal, dass im Code von "Funktionen" nicht mehr viel zu sehen ist.
Frotho schrieb: > Jörg W. schrieb: >> Du solltest dich von Vorstellungen lösen > Ich vermute aber > mal, dass im Code von "Funktionen" nicht mehr viel zu sehen ist. Wie mans nimmt, eine Funktion fängt normal mit einem label an und endet mit einem ret. So versteckt ist das nun nicht. Wenn man nicht gerade extreme Optimierung macht. Das hängt auch weniger von C ab, als vielmehr von der Zielarchitektur. Nur, welche Relevanz hat die ASM Repräsentation für diese Diskussion überhaupt? Es geht um die Lesbarkeit des C Quellcodes.
:
Bearbeitet durch User
Cyblord -. schrieb: > Frotho schrieb: >> Jörg W. schrieb: >>> Du solltest dich von Vorstellungen lösen > >> Ich vermute aber >> mal, dass im Code von "Funktionen" nicht mehr viel zu sehen ist. > > Wie mans nimmt, eine Funktion fängt normal mit einem label an und endet > mit einem ret. So versteckt ist das nun nicht. Wenn man nicht gerade > extreme Optimierung macht. Wobei Funktions-Inlining für mich jetzt keine extreme Optimierung ist, aber da kann man sicher drüber diskutieren... (solange der Scope, die Sichtbarkeit der Funktion nicht ausreichend beschränkt ist, wird sie natürlich trotzdem angelegt, aber ggf. nie angesprungen) > Nur, welche Relevanz hat die ASM Repräsentation für diese Diskussion > überhaupt? Es geht um die Lesbarkeit des C Quellcodes. Da sprach jemand von Overhead durch Funktionsaufrufe, den man in der ASM-Repräsentation vermutlich am Besten sehen kann. MfG, Arno
Frotho schrieb: > Kann man die Adresse von Sprungmarken auslesen, um sie in einer > Sprungtabelle zu speichern? Und natürlich wird das passende Gegenstück > benötigt, ein indirekter Jump-Befehl, der eine Adresse in einer > Sprungtabelle ansteuern kann (Goto will ich das nicht nennen, ich > fürchte Schläge ;-) ) Das geht sogar zur Laufzeit: setjmp/longjump
Cyblord -. schrieb: > Nur, welche Relevanz hat die ASM Repräsentation für diese Diskussion > überhaupt? Es geht um die Lesbarkeit des C Quellcodes. Primär Labelvariable + Sprungtabelle. Die Lesbarbeit ist ein Motiv. Arno schrieb: > Overhead durch Funktionsaufrufe, den man in der > ASM-Repräsentation vermutlich am Besten sehen kann. Wie gemeint?
Das bringt doch nichts. Mach dich mal schlau über die moderne x64 Architektur. Geschwindigkeit holst du da nur raus, wenn du komplett auf Sprünge verzichtest, bzw. die Branch Prediction für dich arbeiten lässt. Dazu gibt es etwa bedingte Befehleserweiterungen. Für fühlbaren Geschwindigkeitsgewinn musst du die SIMD (AVX512 etc.) Erweiterungen verwenden, da wird dann dein lahmer Rechner plötzlich zum Numbercruncher... Das hängt aber inzwischen alles vom genauen Prozessormodell ab. Die x64 Architektur erkennt automatisch Befehlsabhängigkeiten, und führt mehrere Befehle im Hintergrund parallel aus... Daneben wird Register-Renaming gemacht, da intern viel mehr Register vorhanden sind. Wenn du dich da nicht mal ansatzweise eingelesen hast, hast du keine Change echte Performance zu erzielen. Ein guter Link dazu: https://www.agner.org/optimize/ Du brauchst dir nur mal memcpy() Routinen anzuschauen. Die bessren Routinen (Intel Performance Library) sind so schnell, wie es der 1st Level Cache zulässt! Da ist eine einfache Zuweisung in einer for() schleife lahm dagegen... Der Assembler Code ist übrigens sehr gut lesbar, wenn du da noch nicht reingeschaut hast, weisst du noch gar nicht, von was du überhaupt redest... Es ist wirklich verlorene Zeit, über solche Microoptimierungen nachzudenken!
Jörg W. schrieb: > GCC kann sowas als Erweiterung: > > https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html#Labels-as-Values > > Mir ist aber in knapp 30 Jahren C-Praxis noch nichts untergekommen, wo > ich sowas als vorteilhaft erachtet hätte. ;-) Computed-Goto ist sehr praktisch beim Bau eines Interpreters, wo x 100 Ziele (Befehls-Snippets) schnell angesprungen werden sollten. https://eli.thegreenplace.net/2012/07/12/computed-goto-for-efficient-dispatch-tables leo
Udo K. schrieb: > Das bringt doch nichts. Mach dich mal schlau über die moderne > x64 Architektur. ähm..habe unter Mikrocontroller geschrieben > Es ist wirklich verlorene Zeit, über solche Microoptimierungen > nachzudenken! Ich habe den Timer (testweise) im Grenzbereich laufen. Da ist nichts "verlorene Zeit"
Ist schon ein interessantes Thema. Ich habe mal, leider erfolglos, versucht auf einem Bluepill Board in die oberen 64kB Funktionen und Zeichensätze für ein ST7735 Display unter zu bringen. In den unteren 64kB einen Bootloader und die Anwendung. Beide sollten die Grafik Funktionen nutzen ohne diese im oberen Bereich zu verändern. Bin dann leider nicht weiter gekommen und habe aufgegeben. Hat das schon einmal jemand geschafft, so das man nur eine Header Datei einbinden muss und der Compiler sich nicht beschwert und auch nicht versucht die Funktionen selbst zu bauen?
Frotho schrieb: > Arno schrieb: >> Overhead durch Funktionsaufrufe, den man in der >> ASM-Repräsentation vermutlich am Besten sehen kann. > > Wie gemeint? Du warst derjenige, der Overhead ins Spiel brachte :) Woher weißt du, dass ein wie auch immer erstellter Sprung oder ein goto weniger Overhead hat als ein (*function)()? Dazu wirst du doch sicherlich den vom Compiler generierten ASM-Code ansehen, oder nicht? MfG, Arno
Frotho schrieb: > Kann man die Adresse von Sprungmarken auslesen, um sie in einer > Sprungtabelle zu speichern? Nicht wirklich. Wozu auch? C "Sprungmarken" kann man mit C Sprachmitteln direkt anspringen. Wenn man eine Funktion z.B. als solche Marke ansieht, dann kann man durch den Aufruf der Funktion dahin "springen". Dito Labels für goto oder die case: Marken in einem switch() Statement. > Und natürlich wird das passende Gegenstück > benötigt, ein indirekter Jump-Befehl, der eine Adresse in einer > Sprungtabelle ansteuern kann Unter dem vollständigen Verlust von Portabilität kann man einen geeigneten Datentyp (int oder void*) natürlich in einen Funktionszeiger casten und dann dahin springen. So macht man das bspw. im schon genannten Fall des Sprungs in den Bootloader. > Das ist ja nur theoretisch, eine Art "on <Ausdruck> goto <Sprungmarke>". Dafür gibt es ja das switch() Statement in C. Frotho schrieb: > Wer immer nur mit der Herde blökt "goto ist pfui", wird auch immer nur > in seinem (Denk)Gatter bleiben. Manche Gedanken setzen sich aber auch einfach deswegen als richtig durch, weil sie eben richtig sind. > Ein sinnvoller Einsatz > von Goto (außer in absoluten Ausnahmefällen wie bei Fehlern) fällt mir > gerade auch nicht ein (nicht mal in BASIC). Pfui ist es deswegen noch > lange nicht. Gosub habe ich z.B. gerne verwendet. GOSUB ist ein Funktionsaufruf. Den hast du in C natürlich immer noch. Nur halt bequemer, mit Namen. Zeilennummern hat man in BASIC nur deswegen verwendet, weil diese (frühen) BASIC Dialekte noch keine benannten Funktionen hatten. > Für Routinen, die an mehreren > Stellen innerhalb einer Funktion dasselbe tun, war Gosub ideal Häh? Natürlich kannst du auch in C ein und dieselbe Funktion mehrfach innerhalb einer weiteren Funktion aufrufen. Was du wahrscheinlich meinst, ist daß du so eine Funktion nicht nur als Ganzes aufrufen kannst, sondern einen Funktionsaufruf mitten in eine Funktion hinein. Oder eine andere "Optimierung" die ich hin und wieder geshen habe: wenn die letzte Operation innerhalb einer Funktion der Aufrunf einer anderen Funktion ist, dann wird die nicht per CALL/GOSUB aufgerufen, sondern per JMP/GOTO. Das RET/RETURN am Ende dieser Funktion beendet dann die erste Funktion gleich mit. Man spart damit den Stackzugriff für die Returnadresse. Aber das sind Mätzchen. Der Optimierungseffekt ist jenseits von "Hallo Welt!" Programmen nicht nachweisbar. Aber wenn dich C zu sehr von deinen heißgeliebten Assemblertricks fernhält, dann bleib halt bei Assembler. Kannst dich ja mit dem c-hater zusammentun.
Arno schrieb: > Woher weißt du, > dass ein wie auch immer erstellter Sprung oder ein goto weniger Overhead > hat als ein (*function)()? Weil ein Jump nur ein load Programmcounter ist. Weniger (und schneller) geht gar nicht :) Funktionsparameter sind in C by value. Wenn 5 Werte übergeben werden, muss folglich 5x kopiert werden. Wie kann das schneller als ein Jump sein? Selbst mit & vor dem Parameter wird Code generiert. Nehme ich jedenfalls mal an. > Dazu wirst du doch sicherlich den vom > Compiler generierten ASM-Code ansehen, oder nicht? Ja, das werde ich demnächst garantiert tun.
pegel schrieb: > Ist schon ein interessantes Thema. > Ich habe mal, leider erfolglos, versucht auf einem Bluepill Board in die > oberen 64kB Funktionen und Zeichensätze für ein ST7735 Display unter zu > bringen. Sowas ähnliches. Es war noch unter DOS. Ich habe mal den zweiten Zeichensatz der Grafikkarte aktiviert, mit Grafikzeichen geladen und daraus unter DOS eine Art "aufsetzbares Windows" (mit Fenstern und allem pipapo) gebaut. Die Grafik wurde mit den Zeichen 0..31 gesteuert, von CLS bis locate Cursor war alles dabei. Einen Cursor gab es auch, und Mausbedienung. Ging sogar mit Programmen, die keine Maus hatten, z.B. alte COBOL-Programme. Es mussten nur die entsprechenden Steuerzeichen "gedruckt" werden, um die Schnittstelle zum "Windows" zu bedienen. Rückmeldung kam über ReadKey, auch die Cursorposition. Mein "Windows" war blitzschnell, und winzig klein, nur ein paar kb. Ja die guten alten Zeiten. Heute haben wir sie wieder. Das wissen wir aber erst morgen ;)
Axel S. schrieb: >> Ein sinnvoller Einsatz >> von Goto (außer in absoluten Ausnahmefällen wie bei Fehlern) fällt mir >> gerade auch nicht ein (nicht mal in BASIC). Pfui ist es deswegen noch >> lange nicht. Gosub habe ich z.B. gerne verwendet. > > GOSUB ist ein Funktionsaufruf. Den hast du in C natürlich immer noch. Nein ist es eben nicht. Ich will die Funktion nicht verlassen, weil ich dann auch den (lokalen) Datenkontext verlasse. Wenn man das noch nie gebraucht hat, sieht man natürlich keinen Sinn darin. Ist ja auch nicht weiter schlimm. > Häh? Natürlich kannst du auch in C ein und dieselbe Funktion mehrfach > innerhalb einer weiteren Funktion aufrufen. Und wie soll das gehen, wenn ich innerhalb der Funktion z.B. eine Berechnungsroutine aufrufen will. Die muss doch angesprungen werden, und danach muss zum Caler zurückgesprungen werden. also genau das, was GOSUB macht. Oder wo stehe ich jetzt am Schlauch, wie soll das denn in C gehen? > Was du wahrscheinlich meinst, ist daß du so eine Funktion nicht nur als > Ganzes aufrufen kannst, sondern einen Funktionsaufruf mitten in eine > Funktion hinein. Nein. Das habe ich noch nie gebraucht. Ich habe mich vielleicht undeutlich ausgedrückt. Muster hätte ich in VBA, wenn ich suchen soll sage es. > Aber wenn dich C zu sehr von deinen heißgeliebten Assemblertricks > fernhält, dann bleib halt bei Assembler. Kannst dich ja mit dem c-hater > zusammentun. Quatsch. C gefällt mir immer besser. Nicht so gut wie Assembler, aber ich habe mich an die d@@fen geschw. Klammern fast gewöhnt :)
Frotho schrieb: > Funktionsparameter sind in C by value. Wenn 5 Werte übergeben werden, > muss folglich 5x kopiert werden. Wie kann das schneller als ein Jump > sein? Selbst mit & vor dem Parameter wird Code generiert. Nehme ich > jedenfalls mal an. Funktionsparameter lösen sich (zumindest unter selben Bedingungen wie bei einem goto) meist in nichts auf, wenn man Inlining zuläßt oder gar erzwingt. Dann wird da nix kopiert.
Frotho schrieb: > Funktionsparameter sind in C by value. Wenn 5 Werte übergeben werden, > muss folglich 5x kopiert werden. Dein Weltbild ist außerordentlich simpel. Die Realität mag vor 30 Jahren so gewesen sein, seither hat sich im Compilerbau einiges getan. Wenn du Assembler programmieren willst, dann tu's. Wenn du in einer höheren Sprache programmieren willst, hat das nur Sinn, wenn du deren Abstraktions- und Strukturierungsmöglichkeiten auch benutzt. Ja, ich weiß, "Real Programmers can write FORTRAN in any language."
Frotho schrieb: > Arno schrieb: >> Woher weißt du, >> dass ein wie auch immer erstellter Sprung oder ein goto weniger Overhead >> hat als ein (*function)()? > > Weil ein Jump nur ein load Programmcounter ist. Weniger (und schneller) > geht gar nicht :) Dafür hast du am Ende den Speicheroverhead, um wieder irgendwo definiert herauszukommen. Und schneller geht sehr wohl: Das Stichwort Inlining wurde ja schon genannt. > Funktionsparameter sind in C by value. Wenn 5 Werte übergeben werden, > muss folglich 5x kopiert werden. Nein, muss es nicht. Das Programm muss sich so verhalten, als wäre kopiert worden - aber wenn das egal ist (z.B. weil der Parameter nicht verändert wird) dann muss der Compiler auch keinen Code für das Kopieren generieren, und wird das wahrscheinlich in den meisten Fällen auch nicht tun. >> Dazu wirst du doch sicherlich den vom >> Compiler generierten ASM-Code ansehen, oder nicht? > > Ja, das werde ich demnächst garantiert tun. Ich rate sehr dazu, das zu tun, bevor dir manche Annahmen wie Gewissheiten vorkommen. Es gibt verdammt gute Compilerbauer :) MfG, Arno
Arno schrieb: > Ich rate sehr dazu, das zu tun, bevor dir manche Annahmen wie > Gewissheiten vorkommen. Es gibt verdammt gute Compilerbauer :) Vielleicht ist mein Weltbild wirklich beschädigt. Mag daran liegen, dass ich schon zu viele Programme von innen gesehen habe. M$ DOS Kernel war z.B. die ärmste Traurigkeit, die ich je gesehen habe. Die INTs haben sogar den Stack neu "initialisiert", bei jedem Aufruf!! Da habe ich halt gelernt, selbst zu optimieren. Wenn das heute besser ist, würde ich mich wirklich freuen. Gibt es (deutsche) Literatur, WIE ein Compiler sich verhält? Danke allerseits.
Frotho schrieb: > Gibt es (deutsche) Literatur, WIE ein Compiler sich verhält? Was sollte sowas bringen, wer sollte Zeit haben, das zu schreiben? Es ist allemal sinnvoll, sich den vom Compiler generierten Code anzusehen. Ansonsten steigt man dort nur ein, wenn man wirklich am Compiler mit werkeln möchte, und dann ist Englisch sowieso gesetzt.
Frotho schrieb: > Axel S. schrieb: >>> Ein sinnvoller Einsatz >>> von Goto (außer in absoluten Ausnahmefällen wie bei Fehlern) fällt mir >>> gerade auch nicht ein (nicht mal in BASIC). Pfui ist es deswegen noch >>> lange nicht. Gosub habe ich z.B. gerne verwendet. >> >> GOSUB ist ein Funktionsaufruf. Den hast du in C natürlich immer noch. > > Nein ist es eben nicht. Albern. Das GOSUB von BASIC (das meintest du ja wohl) ist sehr wohl ein Funktionsaufruf. Bzw. das BASIC-Äquivalent dessen, was in C ein Funktionsaufruf ist. Damals nannte man das UNTERPROGRAMM. Bzw. englisch SUBROUTINE, daher auch GOSUB für GOto SUBroutine. > Ich will die Funktion nicht verlassen, weil ich > dann auch den (lokalen) Datenkontext verlasse. Genauso albern. BASIC hat keine lokalen Kontexte. Da sind alle Variablen global. Du kannst in C natürlich genauso programmieren, wenn du willst. Alle anderen haben schon erkannt, daß das eine schlechte Idee<tm> ist. Aber irgendwer muß ja der letzte sein. >> Häh? Natürlich kannst du auch in C ein und dieselbe Funktion mehrfach >> innerhalb einer weiteren Funktion aufrufen. > > Und wie soll das gehen, wenn ich innerhalb der Funktion z.B. eine > Berechnungsroutine aufrufen will. Die muss doch angesprungen werden, und > danach muss zum Caler zurückgesprungen werden. also genau das, was GOSUB > macht. Oder wo stehe ich jetzt am Schlauch, wie soll das denn in C > gehen? Hast du noch nie ein C-Programm geschrieben, wo du eine Funktion aufrufst? > Ich habe mich vielleicht undeutlich ausgedrückt. <Loriot> ACH! </Loriot>
Frotho schrieb: > Gosub habe ich z.B. gerne verwendet. Gosub hatte man früher in Basic verwendet, da es Konstrukte wie Funktionen und Prozeduren noch nicht gab. Endlosschleifen mit Abbruchbedingung konnte man nur mit goto schreiben. Jeder Assemblerprogrammierer verwendet nichts anderes.
Frotho schrieb: > Und wie soll das gehen, wenn ich innerhalb der Funktion z.B. eine > Berechnungsroutine aufrufen will. Die muss doch angesprungen werden, und > danach muss zum Caler zurückgesprungen werden. also genau das, was GOSUB > macht. Oder wo stehe ich jetzt am Schlauch, wie soll das denn in C > gehen? Ein Funktionsaufruf vielleicht? Dann springt es dort hin und kehrt am Schluß wieder zum Aufrufer zurück. Kannst du beliebig schachteln. Wenn Du noch irgendeinen Kontext mit Daten mitgeben willst übergibst Du halt noch einen Zeiger auf die Daten. Gcc kann (nicht-standard!) auch lokale Funktionen (Funktionen innerhalb von Funktionen), die sind wie lokale Variablen auch nur lokal sichtbar und haben Zugriff auf alle lokalen Variablem der äußeren Funktion. Die kann man auch beliebig schachteln. Pascal-Programmierer werden das zu schätzen wissen, es kann manchmal ganz nützlich sein. Aber Achtung: Das sind keine Closures, nicht daß jemand auf komische Ideen kommt, das ist alles weiterhin rein Stackbasiert und die kann man nicht nach außen weiterreichen!
:
Bearbeitet durch User
Funktionen sind kein Äquivalent zu gosub, weil Funktionen nur einen Einsprung haben. Mit gosub beliebig viele, wenn man will. Aber es gäbe für alles eine Lösung...
A. S. schrieb: > Funktionen sind kein Äquivalent zu gosub, weil Funktionen nur einen > Einsprung haben. Selbst dafür hat GCC noch eine Extension, soweit ich mich erinnere – aber auch die gehört zu den Dingen "mal gehört, nie gebraucht".
Frotho schrieb: > M$ DOS Kernel war z.B. die ärmste Traurigkeit, die ich je gesehen habe. Und, was vermutest Du, in welcher Programmiersprache das geschrieben wurde? In C jedenfalls nicht; zu den Zeiten gab es noch gar keine vernünftigen C-Compiler.
Rufus Τ. F. schrieb: > zu den Zeiten gab es noch gar keine vernünftigen C-Compiler. MS-DOS ist 10 Jahre jünger als UNIX (sieht man schon an der "Epoche": UNIX zählt ab 1.1.1970, MS-DOS/FAT ab 1.1.1980), und C ist geschrieben worden, damit man UNIX nicht mehr (nur) in Assembler schreiben musste …
Jörg W. schrieb: > Rufus Τ. F. schrieb: >> zu den Zeiten gab es noch gar keine vernünftigen C-Compiler. > > MS-DOS ist 10 Jahre jünger als UNIX (sieht man schon an der "Epoche": > UNIX zählt ab 1.1.1970, MS-DOS/FAT ab 1.1.1980), und C ist geschrieben > worden, damit man UNIX nicht mehr (nur) in Assembler schreiben musste … Zu den Zeiten gab es noch gar keine vernünftig optimierenden C-Compiler. Die Sprache war noch nicht mal so weit, als daß das überhaupt - zumindest in dem Maß, wie das heute möglich ist - gegangen wäre.
Markus F. schrieb: > Zu den Zeiten gab es noch gar keine vernünftig optimierenden C-Compiler. Trotzdem wurde UNIX in C geschrieben. ;-) https://www.quora.com/What-is-UNIX-How-is-it-related-to-C-and-C++ "In 1972 (I think, or ‘73) they wanted to deploy their system on platforms other than the original PDP-11. They wanted to rewrite the kernel in a high level language, which was something of a blasphemy at the time, no one ever heard about an OS kernel that wasn’t in assembly, nor did they imagine one. The high level languages at the time weren’t low level enough, so they had to invent a middle level language to suit their only need: write an (almost) cross-platform OS kernel. And C was born." Natürlich ist das auch miteinander verwoben. Operatoren wie ++ und -- sind vermutlich vor allem deshalb erfunden worden, weil eben eine PDP-11 sowas wie post-increment und pre-decrement bei Zeigerzugriffen bereits in ihrer CPU hatte. Daher findest du in alten C-Quelltexten praktisch auch nur *p++ und *--p, aber nicht anders herum (*p--, *++p). Auf diese Weise konnte man trotz noch nicht allzu gut entwickelter Optimierungen im Compiler trotzdem recht gut auf die CPU abbildbaren Code verfassen. Optimierung auf Quelltextebene … im Prinzip das, was unser TE macht. Nur, dass er dafür halt 40 Jahre zu spät dran ist, mittlerweile braucht man sowas nicht mehr. :)
:
Bearbeitet durch Moderator
Rufus Τ. F. schrieb: > Frotho schrieb: >> M$ DOS Kernel war z.B. die ärmste Traurigkeit, die ich je gesehen habe. > > Und, was vermutest Du, in welcher Programmiersprache das geschrieben > wurde? > In C jedenfalls nicht; zu den Zeiten gab es noch gar keine vernünftigen > C-Compiler. Zumindest nicht in Bill Gates' Garage. Bei den "großen Jungs" bei den Bell Laboratories durchaus. Billie spielte damals noch mit BASIC. Ungefähr das Level, auf dem der TE hängen geblieben ist :( Markus F. schrieb: > Jörg W. schrieb: >> >> MS-DOS ist 10 Jahre jünger als UNIX (sieht man schon an der "Epoche": >> UNIX zählt ab 1.1.1970, MS-DOS/FAT ab 1.1.1980), und C ist geschrieben > > Zu den Zeiten gab es noch gar keine vernünftig optimierenden > C-Compiler. Für einen Betriebssystem-Kernel hat C damals schon gereicht. Nicht daß es von Anfang an perfekt gewesen wäre. Aber wenn es gut genug für UNIX war, wäre es mehr als gut genug für DOS gewesen. Aber natürlich wissen wir alle, daß DOS als Abklatsch von CP/M gestartet ist. Und letzteres war in zum größten Teil in Assembler, in Teilen in PL/M geschrieben.
Axel S. schrieb: > Billie spielte damals noch mit BASIC. Nun, er schrieb das BASIC. Genauer: hat es zum Standard für alle Heimcomputer und erste PCs gemacht. Zudem hat Microsoft DOS nicht entwickelt sondern gekauft. Axel S. schrieb: > Aber wenn es gut genug für UNIX war, wäre es mehr als gut genug für DOS > gewesen. Naja, qdos brauchte nicht portabel zu sein.
Ganz in Ruhe lässt mich das Thema mit den Funktionen im oberen 64k Bereich des Bluepill doch noch nicht. Nach dieser Methode war es kein Problem, Funktionen und Variablen an die gewünschte Adresse zu legen: http://blog.atollic.com/using-gnu-gcc-on-arm-cortex-devices-placing-code-and-data-on-special-memory-addresses-using-the-gnu-ld-linker Gescheitert bin ich daran, die neue Anwendung dazu zu bewegen die vorhandenen Funktionen im oberen Bereich zu benutzen. Wenn ich im linker script den oberen Bereich angebe, versucht der Compiler dort alles neu zu bauen und da fehlen natürlich die Quellen dazu. So ist das auch gedacht. Könnte man eine Funktionstabelle an den Anfang des oberen Bereiches legen die Name und Adresse von Funktion und Variable enthält die vom Compiler wie eine Bibliothek gefunden werden? Also ohne diese neu zu bauen und einfach durch eine Header Datei einzubinden?
A. S. schrieb: > Nun, er schrieb das BASIC. Genauer: hat es zum Standard für alle > Heimcomputer und erste PCs gemacht. Erste PCs: naja, vielleicht. Wenngleich er da schon gegen bswp. Turbo-Pascal anstinken musste. Heimcomputer? Nee, da waren andere vor ihm. Sowas wie C64 ist einfach älter als QuickBasic. Billy war geschäftstüchtig, aber innovativ war er nie. Man hätte sich auch für den 8086-PC bereits etwas besseres als einen CP/M-Abklatsch vorstellen können – siehe Commodore Amiga oder Atari ST. > Zudem hat Microsoft DOS nicht entwickelt sondern gekauft. Hat er, aber damals hat er (bzw. Paul Allen) auch tatsächlich noch selbst Hand angelegt.
Schon bisschen peinlich wie man Microsoft und Bill Gates immer künstlich kleinreden muss. Die Linuxer Seele scheint das zu brauchen.
:
Bearbeitet durch User
Jörg W. schrieb: > Heimcomputer? Nee, da waren andere vor ihm. > Sowas wie C64 ist einfach älter als QuickBasic. Das Commodore-Basic ist aber auch von Microsoft... genauso wie das Basic auf dem Atari.
Cyblord -. schrieb: > Schon bisschen peinlich wie man Microsoft und Bill Gates immer künstlich > kleinreden muss. Wo habe ich ihn „klein geredet“? Ich habe nur geschrieben, dass er alles andere als innovativ war. Einen Gegenbeweis hast du nicht, nur Polemik. Davon abgesehen ging's um Programmiersprachen und insbesondere C. Nicht gerade eine Domäne von Microsoft – so gut wie alles jenseits von C89 haben sie „verschlafen“ bzw. bewusst nichts mehr in der Richtung gemacht. Damit dürften sie unter den C-Compilern größerer Hersteller so ziemlich das unbestrittene Schlusslicht sein. Außerdem ist es natürlich interessant, dass jeder, der ein paar Argumente gegen Microsoft vorträgt, sofort ein „Linuxer“ ist. Das spricht Bände … es geht eben nichts über ein gepflegtes Feindbild. :)
S. R. schrieb: > Jörg W. schrieb: >> Heimcomputer? Nee, da waren andere vor ihm. >> Sowas wie C64 ist einfach älter als QuickBasic. > > Das Commodore-Basic ist aber auch von Microsoft... > genauso wie das Basic auf dem Atari. Ah OK. War mir so nicht bewusst, gerade mal nachgelesen.
Jörg W. schrieb: > A. S. schrieb: > >> Nun, er schrieb das BASIC. Genauer: hat es zum Standard für alle >> Heimcomputer und erste PCs gemacht. > > Erste PCs: naja, vielleicht. Wenngleich er da schon gegen bswp. > Turbo-Pascal anstinken musste. > > Heimcomputer? Nee, da waren andere vor ihm. Sowas wie C64 ist einfach > älter als QuickBasic. Vorsicht! Das Commodore BASIC im C64 ist eine nur geringfügig modifierte Variante des Microsoft BASIC für 6502 [1]. Und ja, diesen BASIC Interpreter hat William Henry tatsächlich selber geschrieben. Oder doch zumindest zum größten Teil. Der Original XT hatte neben dem BIOS auch ein BASIC im ROM. [1] https://en.wikipedia.org/wiki/Commodore_BASIC
Jörg W. schrieb: > Billy war geschäftstüchtig, aber innovativ war er nie. Man hätte sich > auch für den 8086-PC bereits etwas besseres als einen CP/M-Abklatsch > vorstellen können – siehe Commodore Amiga oder Atari ST. Bill Gates ist mit Basic Millionär geworden und hat es in den 70ern zum Standard gemacht. IBM kam zu Microsoft, weil es auf praktisch jedem Rechner lief und bekannt war. Mit Betriebssystemen hatten sie jedoch keine Erfahrung, so dass sie zeitlich und fachlich sicher nicht in der Lage war, da was eigenes zu entwickeln. Ob der Digital-Research-Boss nun Angeln war, als IBM ankloppfte (auf Gates Empfehlung hin), ist am Ende egal, für Microsoft war es ein Glücksfall. Aber das schlechte DOS kann man ihm kaum vorwerfen, das war weder seine Domäne noch sein Anspruch (da kompetent zu sein).
Axel S. schrieb: > Vorsicht! Yo, hatte ja kurz vor dir schon jemand angemerkt. Seit ich Turbo-Pascal hatte (schon auf CP/M), brauchte ich aber kein BASIC mehr. :)
A. S. schrieb: > Aber das schlechte DOS kann man ihm kaum vorwerfen, das war weder seine > Domäne noch sein Anspruch (da kompetent zu sein). Nö, er hat es halt nur verkauft. Sowas konnte er immer gut. :) Das es "quick and dirty" hieß, schien ihn aber schon gestört zu haben, es musste dann noch schnell umbenannt werden …
> Der Original XT hatte neben dem BIOS auch ein BASIC im ROM.
Bis in die 486/Pentium-Zeit gab es dann ja auch die bekannte
Fehlermeldung "no basic ROM found", wenn kein Bootsector gefunden wurde.
Ursprünglich war es halt so, daß ein Computer immer mit
Programmiersprache geliefert wurde. (War auch sinnvoll, weil es für
viele Modelle kaum Software gab.)
IBM hat die Marktchancen der PCs einfach stark unterschätzt, sonst
hätten sie vermutlich ein eigenes OS entwickelt. Später haben sie dann
noch OS/2 nachgeschoben, aber da war es bereits zu spät.
Angeblich sollte der Raspi an diese Tradition anknüpfen und mit einem
Python-Interpreter im ROM ausgestattet werden, daher auch das PI im
Name.
Und BTT: BASIC ohne goto und gosub wäre kaum vorstellbar. ;-))
svensson schrieb: > Ursprünglich war es halt so, daß ein Computer immer mit > Programmiersprache geliefert wurde. Naja, nicht wirklich: CP/M-Computer (die man sicherlich als eine Art Vorläufer der PCs ansehen kann, eine andere Linie als all die Heimcomputer) hatten von Haus aus nichts dabei.
Jörg W. schrieb: > Naja, nicht wirklich: CP/M-Computer (die man sicherlich als eine Art > Vorläufer der PCs ansehen kann, eine andere Linie als all die > Heimcomputer) hatten von Haus aus nichts dabei. Ich meine, beim Schneider (Amstrad CPC) wäre damals eine Diskette dabeigelegen. Weiß aber nicht mehr ganz genau.
svensson schrieb: > Und BTT: BASIC ohne goto und gosub wäre kaum vorstellbar. ;-)) Schön, dass ihr wieder beim Topic seid. Ich freue mich ;-)
A. S. schrieb: > IBM kam zu Microsoft, weil es auf praktisch jedem Rechner lief und > bekannt war. Mit Betriebssystemen hatten sie jedoch keine Erfahrung, so > dass sie zeitlich und fachlich sicher nicht in der Lage war, da was > eigenes zu entwickeln. Dass es allein mit fehlender Erfahrung erklärbar ist, dass man einen Adressraum oben dich macht, stelle ich in Zweifel. Das darf einem Schüler passieren, aber keiner Weltfirma. Dieser Schnellschuss hat jahrelang der Fachwelt extremste Probleme bereitet. Aber da haben sich IBM, Microsoft und Intel die Hand gegeben: von allem nur das allerschlechteste. Ich kam damals aus einer Z80-Architektur (CPC 464,15 bekannte Fehler im OS) und dachte, mich trifft der Schlag ....
Frotho schrieb: > A. S. schrieb: > > Dass es allein mit fehlender Erfahrung erklärbar ist, dass man einen > Adressraum oben dich macht, stelle ich in Zweifel. Das darf einem > Schüler passieren, aber keiner Weltfirma. Dieser Schnellschuss hat > jahrelang der Fachwelt extremste Probleme bereitet. Aber da haben sich > IBM, Microsoft und Intel die Hand gegeben: von allem nur das > allerschlechteste. Den auf 640kB limitierenden Graphikspeicher hat der Bill aber nicht eingelötet. Und er hat der CPU auch keine Adressleitungen abgezwickt. > Ich kam damals aus einer Z80-Architektur (CPC 464,15 bekannte Fehler im > OS) und dachte, mich trifft der Schlag .... Vielleicht sollte die 640k-Grenze aber bei den Z80-Usern einen Wiedererkennungseffekt bewirken ;-)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.