Übersetzungsverhältnis 1:1, 1:n bei Programmierung

Tach’chen,

was ist denn unter dem Übersetzungsverhältnis von Compilern und Interpretern (=Assemblierer??) zu verstehen? Hat jemand ein plakatives Beispiel?

Danke
TTR

Hallo,

wahrscheinlich soll damit gemeint sein, dass bei Assembler aus einer Zeile genau ein Maschinenbefehl entsteht (1:1), aber so streng stimmt das längst nicht mehr. Ein Compiler erzeugt jedenfalls viel mehr Maschinencode pro Zeile Programm (im Durchschnitt, manche Zeile erzeugt auch garkeinen). Es gibt Compiler, die machen aus „print (‚hello world‘)“ ein Programm mit 180 kB, ich komme in Assembler damit in etwa 30 bytes hin.

Gruss Reinhard

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hallo Reinhard,

wahrscheinlich soll damit gemeint sein, dass bei Assembler aus
einer Zeile genau ein Maschinenbefehl entsteht (1:1), aber so
streng stimmt das längst nicht mehr. Ein Compiler erzeugt
jedenfalls viel mehr Maschinencode pro Zeile Programm (im
Durchschnitt, manche Zeile erzeugt auch garkeinen). Es gibt
Compiler, die machen aus „print (‚hello world‘)“ ein Programm
mit 180 kB, ich komme in Assembler damit in etwa 30 bytes hin.

Das ist aber ein unfairer Vergleich :smile:

Cstartup initialisiert dir die Variablen, stellt deinem Main die Aufrufparameter bereit, öffnet für dich stdin, stdout, stderr, usw.
Und du benutzt nichts davon und beschwerst dich über die Codegrösse !!
:wink:)

MfG Peter(TOO)

Hallo TTR,

was ist denn unter dem Übersetzungsverhältnis von Compilern
und Interpretern (=Assemblierer??) zu verstehen? Hat jemand
ein plakatives Beispiel?

Bei 1:1 wird dein Code eben 1:1 übersetzt, egal wie ungeschickt der ist.
Im anderen Fall nimmt der Compiler, oder bei modernen CPUs aus der Assembler, Optimierungen vor.
Ein typischer Fall ist, wenn die CPU z.B. eine FPU besitzt. Diese arbeitet parallel zur CPU, benötigt aber für viele Aufgaben recht lange.
Also mal ein Beispiel:

10 Lade FPU mit Wert#1
20 Lade FPU mit Wert#2
30 Multipliziere FPU Wert#1 mit Wert#2
40 Speichere FPU Resultat im Speicher
50 Lade ALU mit Wert#1
60 Lade ALU mit Wert#2
70 Multipliziere ALU Wert#1 mit Wert#2

In Zeile 40 muss gewartet werden bis das Resultat berechnet wurde.
Optimieren könnte man z.B. so:

10 Lade FPU mit Wert#1
20 Lade FPU mit Wert#2
40 Multipliziere FPU Wert#1 mit Wert#2
50 Lade ALU mit Wert#1
60 Lade ALU mit Wert#2
70 Multipliziere ALU Wert#1 mit Wert#2
80 Speichere FPU Resultat im Speicher

Solange die FPU beschäftigt ist, kann die ALU parallel dazu arbeiten.

Bei vielen RISC-CPUs ist es z.B. so, dass der Befehl nach einem RET immer ausgeführt wird. Statt:


60 STORE A,…
70 RET
80 NOP

Schreibst du


60 RET
70 STORE A,…

Je nachdem übernimmt der Assembler das für dich, übersetzt den Code also nicht 1:1

Bei Hochsprachen kann man natürlich noch viel mehr optimieren:
Aus

int i;
int a = 0;

for ( i = 0; i 
kann ein Compiler folgendes machen:
 i = 10;
 a = 30;


MfG Peter(TOO)

Hallo TTR,

was ist denn unter dem Übersetzungsverhältnis von Compilern
und Interpretern (=Assemblierer??) zu verstehen? Hat jemand
ein plakatives Beispiel?

Bei 1:1 wird dein Code eben 1:1 übersetzt, egal wie
ungeschickt der ist.
Im anderen Fall nimmt der Compiler, oder bei modernen CPUs aus
der Assembler, Optimierungen vor.
Ein typischer Fall ist, wenn die CPU z.B. eine FPU besitzt.
Diese arbeitet parallel zur CPU, benötigt aber für viele
Aufgaben recht lange.
Also mal ein Beispiel:

10 Lade FPU mit Wert#1
20 Lade FPU mit Wert#2
30 Multipliziere FPU Wert#1 mit Wert#2
40 Speichere FPU Resultat im Speicher
50 Lade ALU mit Wert#1
60 Lade ALU mit Wert#2
70 Multipliziere ALU Wert#1 mit Wert#2

In Zeile 40 muss gewartet werden bis das Resultat berechnet
wurde.
Optimieren könnte man z.B. so:

10 Lade FPU mit Wert#1
20 Lade FPU mit Wert#2
40 Multipliziere FPU Wert#1 mit Wert#2
50 Lade ALU mit Wert#1
60 Lade ALU mit Wert#2
70 Multipliziere ALU Wert#1 mit Wert#2
80 Speichere FPU Resultat im Speicher

Solange die FPU beschäftigt ist, kann die ALU parallel dazu
arbeiten.

Bei vielen RISC-CPUs ist es z.B. so, dass der Befehl nach
einem RET immer ausgeführt wird. Statt:


60 STORE A,…
70 RET
80 NOP

Schreibst du


60 RET
70 STORE A,…

Je nachdem übernimmt der Assembler das für dich, übersetzt den
Code also nicht 1:1

Bei Hochsprachen kann man natürlich noch viel mehr optimieren:
Aus

int i;
int a = 0;

for ( i = 0; i
kann ein Compiler folgendes machen:
i = 10;
a = 30;

1:1 steht also für: „Ein Befehl des Quelltextes wird zu einem Befehl in Object Code übersetzt“?
1:n steht dann für: "Ein Befehl des Quelltextes wird zu n Befehlen in Object Code reduziert, wobei n

Hi TTR,

ein Compiler bietet Befehle an, die schon beinahe aus der Umgangssprache stammen könnten, macht aus einem solchen Befehl wie SQRT eine interne Folge von vielleicht 20, vielleicht 1000 Maschinenbefehlen und erzeugt aus einem Paket von Befehlen ein lade- oder lauffähiges Programm, meit ein .exe. Der Assembler versteht nur Befehle, die im Prinzip Maschinenbefehle sind wie LoadRegister, SkipIfZero und ähnliches. Derartige Befehle übersetzt er zu einem ausführbaren Programm. Der Interpreter wiederum ist selbst ein ausführbares programm, das die Eingabebefehle interpretiert, also einen nach dem anderen übersetzt und ausführt. Deshalb Interpreter nicht= Assemblierer.

Gruß Ralf

Hallo TTR,

1:1 steht also für: „Ein Befehl des Quelltextes wird zu einem
Befehl in Object Code übersetzt“?

Ja.
Kann aber auch bedeuten, dass die Anweisungen in der selben Reihenfolge ausgeführt werden, wie sie im Quellcode stehn.

Allerdings ist jetzt noch das Problem, dass wir nicht wissen in welchem Kontext deine Frage steht.

1:n steht dann für: "Ein Befehl des Quelltextes wird zu n
Befehlen in Object Code reduziert, wobei n 1

Jede Hochsprache muss schlussendlich in das übersetzt werden, was die CPU auch ausführen kann. Der Trick besteht ja darin, dass ein Computer komplexe Dinge mit ganz einfachen Elementen bewältigt. Das muss auch der Programmierer zuerst tun, mal ganz unabhängig von der Programmiersprache.

So zum Beispiel:
auf der anderen Strassenseite ist ein Laden und ich sage dir: „Der Kaffe ist alle, hohl mal welchen!“.

Und jetzt versuchst du das ganze mal einem Computer beizubringen.
Zuerst muss er mal den Weg finden, wenn du ihm treppensteigen nicht beibringst ist schon mal Ende.
Was macht man mit Türen und wie erkennt man die überhaupt.
Er sollte es auch über die Strasse schaffen, ohne gleich als Flunder zu enden.
Andere Fussgänger sollte man auch noch beachten …
Was ist Kaffee und woran erkennt man das ??
Bezahlen gehört auch zum einkaufen, aber was ist Geld ??

Einem Computer musst du, wa eine einfache Aufgabe für dich ist, erst
Teilchen für Teilchen beibringen undnicht vergessen auch zu berücksichtigen, was zu tun ist, wenn etwas nicht klappt, z.B. der Laden geschlossen ist. So ein einfacher Computer würde halt einfach warten bis die Tür aufgeht … das kann dauern, wenn gerade Samstag Abends ist !!

Ist Assemblierer ein anderes Wort für Interpreter?

NEIN.
Assembler ist Maschinensprache. Esgibt im Prinzip als Befehle nur das, was die CPU ausführen kann. Damit es für den Menschen „verständlicher“ wird, werden die Befehle mit Buchstabenkürzeln (Mnemonics) angegeben. Das versteht die CPU aber nicht, das muss erst noch in Zahlen umgewandelt werden, was aufgabe des Assemblers ist.
Übrigens der Begriff Mnemonic stammt von Lady Ada, das war die erste Programmiererin der Welt. Such mal nach Babbage.

Dann gibt es Compiler und Interpreter, welche nur bei höheren Sprachen verwendet werden.
Ein Compiler überstzt immer das ganze Programm und erzeugt daraus Code für die CPU. Das Programm wird einmal übersetzt und kann dann beliebig oft ausgeführt werden ohne den Compiler zu benötigen.

Ein Interpreter übersetzt Zeilenweise und führt diese Zeile dann sofort aus, danach wird die nächste Zeile im Programm übersetzt und ausgeführt. Soll eine bereits einmal ausgefühte Zeile nochmals ausgeführt werden, so muss sie zuerst nochmals übersetzt werden.

Nicht alle Programmiersprachen sind interpreter-tauglich.
Das Programm für einen Interpreter ist allerdings wesentlich kleiner als das für einen Compiler, dafür ist ein Interpreter langsamer als ein Compiliertes Programm. Andererseits hat der Interpreter den Vorteil, dass man das Programm anhalten kann, am Code was ändern und dann weiterfahren kann.

Um dich noch weiter zu verwirren: Es gibt noch zwischen-Dinger, zwischen Compiler und Interpreter. Die wurden dann „Interpiler“ oder „Compreter“ genant.

MfG Peter(TOO)

1 Like

Ist Assemblierer ein anderes Wort für Interpreter?

NEIN.
Assembler ist Maschinensprache. Esgibt im Prinzip als Befehle
nur das, was die CPU ausführen kann. Damit es für den Menschen
„verständlicher“ wird, werden die Befehle mit
Buchstabenkürzeln (Mnemonics) angegeben. Das versteht die CPU
aber nicht, das muss erst noch in Zahlen umgewandelt werden,
was aufgabe des Assemblers ist.
Übrigens der Begriff Mnemonic stammt von Lady Ada, das war die
erste Programmiererin der Welt. Such mal nach Babbage.

Dann gibt es Compiler und Interpreter, welche nur bei höheren
Sprachen verwendet werden.
Ein Compiler überstzt immer das ganze Programm und erzeugt
daraus Code für die CPU. Das Programm wird einmal übersetzt
und kann dann beliebig oft ausgeführt werden ohne den Compiler
zu benötigen.

Ein Interpreter übersetzt Zeilenweise und führt diese Zeile
dann sofort aus, danach wird die nächste Zeile im Programm
übersetzt und ausgeführt. Soll eine bereits einmal ausgefühte
Zeile nochmals ausgeführt werden, so muss sie zuerst nochmals
übersetzt werden.

Nicht alle Programmiersprachen sind interpreter-tauglich.
Das Programm für einen Interpreter ist allerdings wesentlich
kleiner als das für einen Compiler, dafür ist ein Interpreter
langsamer als ein Compiliertes Programm. Andererseits hat der
Interpreter den Vorteil, dass man das Programm anhalten kann,
am Code was ändern und dann weiterfahren kann.

Um dich noch weiter zu verwirren: Es gibt noch
zwischen-Dinger, zwischen Compiler und Interpreter. Die wurden
dann „Interpiler“ oder „Compreter“ genant.

Der Assemblierer ist also ein Compiler, der Assembler in Maschinensprache übersetzt und den normalsterbliche heutzutage nicht mehr brauchen, weil in Assembler sowieso nur noch die Freaks und manche Spezialisten schreiben? :wink:

Danke
TTR

Der Assemblierer ist also ein Compiler, der Assembler in
Maschinensprache übersetzt und den normalsterbliche heutzutage
nicht mehr brauchen, weil in Assembler sowieso nur noch die
Freaks und manche Spezialisten schreiben? :wink:

Das hört sich tendenziell so an, als ob Assembler nur noch rückständige Idioten benutzen, die die Zeichen der Zeit nicht erkannt haben - so ist das nicht, wer einen Compiler benutzt, greift auf die Arbeit der Assembler-„Freaks“ zurück, die haben ihm nämlich schon den schwierigsten Teil der Arbeit abgenommen. Im Wesentlichen ist es immer noch so, dass der Compiler für den Aufruf sqrt (x) ein Unterprogramm einsetzt, das ein (menschlicher!) Assembler-Programmierer entworfen hat und das die Wurzel so effektiv wie möglich berechnet.

Es geht also um die in modernen Gesellschaften übliche Arbeitsteilung, die (Assembler) Spezialisten erledigen die aufwendige Drecksarbeit, und Benutzer von C, Basic usw. bauen darauf auf.

Gruss Reinhard

Cstartup initialisiert dir die Variablen, stellt deinem Main
die Aufrufparameter bereit, öffnet für dich stdin, stdout,
stderr, usw.
Und du benutzt nichts davon und beschwerst dich über die
Codegrösse !!
:wink:)

MfG Peter(TOO)

Hallo Peter,

genau darüber beschwere ich mich ja, es geht nämlich auch anders. Im Embedded-Bereich bin ich „Scanning“ Linker gewöhnt, die linken nur das zum Programm, was auch benutzt wird. Habe ich keine Floats, werden auch keine float-Routinen gelinkt, benutze ich bei Floats keine Multiplikation, so wird aus der Float-Bibliothek eben nur add und sub gelinkt usw. Das das aufwendig ist (für den Linker) ist schon klar.

Im PC-Umfeld macht man sich die Mühe nicht, sondern linkt einfach die gesamte Runtime-Bibliothek zum Programm dazu. Man kann ja der Meinung sein, bei Arbeitsspeicher im GB-Bereich spielen MB hin oder her keine Rolle, aber für mich bleibt Verschwendung eben Verschwendung - da bin ich hoffnunglos altmodisch. Vielleicht bin ich dabei auch nicht so ganz allein, die Waschmaschinen mit 64bit-Prozessor und hunderten von MB Ram lassen ja immer noch auf sich warten, trotz des angekündigten Internetanschlusses für jede Haushaltsmaschine weltweit.

Gruss Reinhard

Hallo Reinhard,

Cstartup initialisiert dir die Variablen, stellt deinem Main
die Aufrufparameter bereit, öffnet für dich stdin, stdout,
stderr, usw.
Und du benutzt nichts davon und beschwerst dich über die
Codegrösse !!
:wink:)

genau darüber beschwere ich mich ja, es geht nämlich auch
anders. Im Embedded-Bereich bin ich „Scanning“ Linker gewöhnt,
die linken nur das zum Programm, was auch benutzt wird. Habe
ich keine Floats, werden auch keine float-Routinen gelinkt,
benutze ich bei Floats keine Multiplikation, so wird aus der
Float-Bibliothek eben nur add und sub gelinkt usw. Das das
aufwendig ist (für den Linker) ist schon klar.

Ich bin auch hauptsächlich im Embedded-Bereich zu Hause.

Im PC-Umfeld macht man sich die Mühe nicht, sondern linkt
einfach die gesamte Runtime-Bibliothek zum Programm dazu. Man
kann ja der Meinung sein, bei Arbeitsspeicher im GB-Bereich
spielen MB hin oder her keine Rolle, aber für mich bleibt
Verschwendung eben Verschwendung - da bin ich hoffnunglos
altmodisch.

Du machst hier aber einen kleinen Denkfehler:

Vernünftigerweise linkt man hier nicht statisch, sondern verwendet eine DLL, welche dann vom Betriebssysten (BS) verwaltet wird. Da heutige BS im PC-Bereich multitaskingfähig sind, wird die Bibliothek auch nur einmal in den Speicher geladen, zumindest der Code. Das funktioniert aber nur, wenn nicht jdes Programm seine eigene DLL erstellt …

Zudem gab es z.B. bei Win 3.xx die Möglichkeit bei DLLs anzugeben, welche Funktionen vom BS dauernd in den Speicher geladen werden und welche nur bei Bedarf. Leider haben das die wenigsten Programmierer verstanden. Dadurch gab es das Problem, dass die Beendigungs-Funktion ausgelagert wurde, wodurch sich dann Programme, bei Speichermangel, nicht mehr beenden liessen … Die meisten Programmierer behalfen sich dann damit, dass einfach alles geladen wurde …
Bei den neueren WINs ist diese Aufgabe nun dem BS überlassen worden.

MfG Peter(TOO)

Hallo TTR,

Der Assemblierer ist also ein Compiler, der Assembler in
Maschinensprache übersetzt und den normalsterbliche heutzutage
nicht mehr brauchen, weil in Assembler sowieso nur noch die
Freaks und manche Spezialisten schreiben? :wink:

JAIN.
Ein Assembler übersetzt Maschinensprache in Maschinencode.
Ein Compiler übersetzt eine Hochsprache in Maschinencode.

Im Prinzip ist eine Hochsprache von der verwendeten CPU unabhängig.
Das brühmte „Hello world“-Programm kann ohne eine Änderung auf jedem Computer für welchen ein C-Compiler existiert übersetzt und ausgeführt werden, egal wie exotisch die Rechnerarchitektur ist.

Ein in Assembler geschriebenes Programm muss aber immer an die verwendete CPU angepasst, bzw. neu geschrieben, werden. Selbst Änderungen an der Hardware, ziehen Änderungen am Programm mit sich.

In Assembler hast du Zugriff, und auch die Verantwortung für deren richtige Verwendung, auf alle Register. Ein Compiler lässt dich gar nicht erst „so nahe“ an die CPU ran.
Dafür ist ein Programm in Assembler fast immer kleiner und schneller als eines welches ein Compiler erstellt hat.

Es gibt so einen Erfahrungswert, welcher sich seit Jahrzehnten nicht verändert hat:
Ein Programmierer schaft 10 Zeilen Code pro Tag.
Darin ist der ganze Aufwand für Analyse, testen, debuggen, die Dokumentation usw. enthalten.
Dadurch ergibt sich eine höhere Produktivität in einer Hochsprache als in Assembler.

Aber wie Reinhard geschrieben hat, greifst du auf Assembler zurück. Auch der eigentliche Code-Generator deines Compilers, kann nur von jemandem geschrieben werden, der sich sehr gut mit der Maschinensprache auskennt.

Dann gibt es den Bereich, wo Geräte in sehr grossen Stückzahlen hergestellt werden und somit die Matrialkosten, wesentlich höher als die ENtwicklungskosten sind. Hier macht es sich oft bezahlt, das Programm in Assembler zu schreiben, wenn man dadurch einen leistungsschwächeren Prozessor verwenden kann.
Wenn es also um 100’000 Stück geht und du durch Assembler 1 Euro beim Prozessor einsparen kannst, darf die Entwicklung im Prinzip 100’000 Euro mehr kosten…

MfG Peter(TOO)