C programmieren: Wie arbeitet ein C-Compiler? (2024)

C programmieren: Wie arbeitet ein C-Compiler?

Prof. Dr. Christian Siemers *

Wie entsteht aus geschriebenem C-Code ein Programm, dass das Zielsystem auch versteht und Umsetzen kann? In diesem Beitrag sehen wir uns Aufbau und Arbeitsweise des C-Compilers genauer an.

Unser vorheriger Grundlagenartikeln zum Programmiere mit C befasste sich speziell mit der Standardbibliothek und dem Präprozessor der Programmiersprache. Speziell letzterer ist eines der Elemente, mit dem geschriebener C-Code auch in eine Form umgewandelt wird, die der Rechner umsetzen kann, die sog. Maschinensprache. Dieser Vorgang nennt sich auch Compiling.

Die vier Compilerphasen beim Programmieren mit C

Die Übersetzung eines in C geschriebenen Programms erfolgt in insgesamt vier Phasen, von denen der Compiler an zweien unmittelbar beteiligt ist. Die vier Phasen sind:

Bildergalerie

Bildergalerie mit 12 Bildern
  • Präprozessorphase
  • Frontendphase des Compilers
  • Backendphase des Compilers
  • Linkerphase

Die Präprozessorphase wurde bereits erwähnt. Hierbei handelt es sich um eine Vorbereitung des zu übersetzenden Sourcecodes. Textmakros werden ersetzt, die so genannten include-Dateien eingesetzt, Kommentare gelöscht, die Zeilen immer durch ein Newline-Zeichen getrennt usw. Der Output dieser Phase ist ein reiner Sourcecode, der bislang noch keine Überprüfung oder Übersetzung erfahren hat.

Im Frontend des Compilers (siehe Bild 1) wird dieser Sourcecode eingelesen (Scanner) und überprüft (Parser). Ziel ist es dabei, die korrekte Syntax zu überprüfen, eine erste Syntaxumwandlung und erste Optimierungen durchzuführen. Das Ziel dieser Phase ist ein Zwischencode, der noch von dem Zielsystem (dem Mikroprozessor) unabhängig ist, aber dennoch die Umsetzung in Assembler- oder Maschinensprache vorbereitet. Der Output dieses Frontendteils wird im nächsten Abschnitt genauer betrachtet.

Im Backend des Compilers erfolgt das Einlesen des Zwischencodes (intermediate representation, IR), die Umsetzung in Assemblersprache einschließlich der maschinenspezifischen Optimierung und der Assemblerlauf. Ziel dieses Abschnitts ist der so genannte Objektcode, der neben dem Maschinencode – noch unvollständig – auch Informationen zu den Daten und Programmabschnitten mitführt.

Der Linker liest dann abschließend den Objektcode ein, dazu die angegebenen Standard- und spezifischen Bibliotheken, und fügt das zusammen. Nunmehr sind alle Adressen, auch die der aus der Bibliothek genutzten Funktionen (wie etwa printf) bekannt, und der Maschinencode kann mit allen Adressen vervollständigt werden. Output des Linkers ist ein ausführbarer Maschinencode (in einem File-format).

Die Erzeugung des Zwischencodes

Für den Zwischencode existiert kein genormtes Format, jeder Compiler nutzt dort seine hauseigene Syntax. Besonders interessant ist jedoch das Lance2-Compiler-System, das aus C ein low-level-C erzeugt und dieses als Zwischencode nutzt. Diese Untermenge von C, die dieses Compilersystem als Zwischencode (Intermediate Representation, IR) nutzt, ist natürlich beschränkt. Wesentliche Merkmale sind:

Anweisungen (Statements):

  • Zuweisungen (Assignments): a = b + c, y = function( a, b ), ...
  • Sprünge (Jumps): goto label_1; (diese Sprünge sind Compiler-berechnet und somit ”zugelassen“)
  • Bedingte Sprünge (Conditional Jumps): if( cond ) goto label_2;
  • Marken (Label): label_1:
  • Rücksprung ohne Rückgabewert (return void): return;
  • Rücksprung mit Rückgabewert (return value): return x;

Ausdrücke (Expressions):

  • Symbole: main, a, count …
  • Binäre Ausdrücke (binary expressions): a * b, x / y …
  • Unäre Ausdrücke (unary expressions): ~a, *p …
  • Type Casts: (int), (char)
  • Konstanten (in verschiedenen Formaten): -5, 3.141592653589

Ein kurzer Blick in die obige Liste verrät, dass bei den Anweisungen Schleifen wie for, while und do .. while komplett fehlen. Diese Schleifen werden durch die aufgezählten Konstrukte abgebildet bzw. in diese übersetzt, und es gilt noch zu zeigen, wie dies erfolgt.

Der wichtigste Zusatz, das Zwischencodeformat betreffend, besteht noch in der Beschränkung der Ausdrücke und der Zuweisungen: Sie werden auf ein 3-Adressformat eingeschränkt, d.h., eine Wertzuweisung an ein links stehendes Symbol (a = ...) wird rechtsseitig durch einen unären oder einen binären Ausdruck bestimmt. Längere „Kettenrechnungen“ müssen dementsprechend in Teilrechnungen mit Einfügung temporärer Variablen geteilt werden, eine Aufgabe, die dem Compiler zufällt. Der Grund für diese Einschränkung ist sehr offen-sichtlich: Dem 3-Adressformat entsprechen häufig direkt Assemblerbefehle (etwa: ADD R3, R1, R2, was R3 = R1 + R2 bedeutet).

Bild 2 zeigt die Übersetzung einer if/else if/else-Verzweigung. Dabei wird deutlich, dass nur if-Konstrukte mit anschließendem Sprung (also zusammengefasst der ”bedingte Sprung“) genutzt werden. Die Bedingungen selbst müssen dabei invertiert ausgewertet werden, da ja die Liste der Anweisungen, die bei Erfüllung der ursprünglichen Bedingung auszuführen sind, nun übersprungen werden.

Dies mag etwas holprig wirken, denn bei Zulassung einer üblichen if-Verzweigung wäre dies wesentlich einfacher zu übersetzen. Diese Form der Übersetzung hat jedoch den entscheidenden Vorteil, dass nur bedingte Sprünge verwendet werden, und die lassen sich 1:1 in eine Sequenz von Assemblerbefehlen übersetzen, wie etwa:

cmp R1, R2; (Auswertung der Bedingung)
beq LABEL_IF_1;

Bild 3 zeigt die Übersetzung der while-Schleife, Bild 4 die der etwas komplexeren for-Schleife. In beiden Fällen werden bedingte und unbedingte Sprünge verwendet, um die Schleifenstruktur entsprechend abzubilden, wobei die Bedingung auch wieder invertiert verwendet werden müssen, um den Sprung aus der Schleife zu beschreiben. Entsprechend den hier gezeigten Codeabschnitten können nun auch die switch/case-Verzweigung (Bild 5) und die do..while-Schleife (Bild 6) übersetzt werden, wobei die Mehrfach-Fallunterscheidung (switch/case) etwas komplexer ist.

(ID:45439187)

C programmieren: Wie arbeitet ein C-Compiler? (2024)

FAQs

How to download a compiler for C? ›

Steps for downloading the C compiler for Windows
  1. Google the C compiler for Windows that you wish to download – in this case, MinGW.
  2. Click on the first result, and arrive at their downloads page.
  3. Click on the download button. Your C installer for Windows download should begin after this.
May 20, 2024

Which compiler can you use to translate C programs? ›

Compilers targeting C
NameSupported languagesSupported targets
BaCon (Basic Converter)BasicC
bc9BasicBasicC
BiglooSchemeC
BlechBlechC
90 more rows

What are the steps in compiling a C program? ›

The compilation process can be divided into four steps, i.e., Pre-processing, Compiling, Assembling, and Linking.

How to work a compiler? ›

During the compilation process, a compiler can generate one or more intermediate code forms. “After syntax and semantic analysis of the source program, many compilers generate an explicit low-level or machine-like intermediate representation, which we can think of as a program for an abstract machine.

What compiler should I use for C? ›

In general, GCC and Clang are known for their efficient optimizations, making them among the fastest C compilers.

Which C compiler for Windows? ›

If you want to run C or C++ programs in your Windows operating system, then you need to have the right compilers. The MinGW compiler is a well known and widely used software for installing GCC and G++ compilers for the C and C++ programming languages.

How to practice C programming on a laptop? ›

Your First Program in C
  1. Step 1: Download Dev/C++ For this section, I am running on a Windows 7 operating system. ...
  2. Step 2: Install Dev/C++ Open the file. ...
  3. Step 3: Create First Project. Run Dev/C++ ...
  4. Step 4: Write Your Program. ...
  5. Step 5: Save and Compile Code. ...
  6. Step 6: Run Your Code. ...
  7. Step 7: More Resources. ...
  8. 13 Comments.

How to compile a program? ›

Step 1: Open your terminal, navigate to the directory containing your C file using the cd command. Step 2: Type gcc myfile. c -o hello to compile your C file. The -o hello part of the command names the output file "hello".

Which is the best online C compiler? ›

The Scaler Online C compiler provides the following features: Free Usage: No charges are levied for using the compiler. No Software Installation: You can directly write and compile code without any setups.

How does compiling code work? ›

A code compiler translates human-readable code into a machine language that speaks directly to the CPU. It's a complex process because CPUs are legitimately complex (even more complex than a mousetrap), but also because the process is more flexible than it strictly "needs" to be.

What is the compiler in C with an example? ›

A compiler is a software that converts the source code to the object code. In other words, we can say that it converts the high-level language to machine/binary language. Moreover, it is necessary to perform this step to make the program executable. This is because the computer understands only binary language.

What is the shortcut key to compile a program in C? ›

To compile and run a program, hit ctrl-F9. To view your program results after running (from the IDE), type alt-F5. Use F4 to run your program to the line highlighted by the cursor.

What are the keys to compile C program? ›

Ctrl-Key sequences
ShortcutDescription
Ctrl-BCompile Only (no download prompt)
Ctrl-Shift-BCompile All & Download (clean build)
Ctrl-CCopy(with text selection only)
Ctrl-Shift-CCommit
23 more rows

How is the C compiler written? ›

The original C compiler was written in PDP-7 assembly language, as was Unix at the time; the port to the PDP-11 was also in assembly language. Later, C was used to rewrite the Unix kernel to make it portable.

How to compile in C VS Code? ›

Use keys Cmd + Shift + B to compile and run the C language codes in VSCode.

How to compile using gcc in C? ›

Type gcc c –o [program_name].exe [program_name]. c and press ↵ Enter . Replace “[program_name]” with the name of your source code and application. Once the program is compiled, you'll return to the command prompt without errors.

How to compile C program using make command? ›

c -I. If you put this rule into a file called Makefile or makefile and then type make on the command line it will execute the compile command as you have written it in the makefile. Note that make with no arguments executes the first rule in the file.

References

Top Articles
Latest Posts
Article information

Author: Otha Schamberger

Last Updated:

Views: 5629

Rating: 4.4 / 5 (75 voted)

Reviews: 90% of readers found this page helpful

Author information

Name: Otha Schamberger

Birthday: 1999-08-15

Address: Suite 490 606 Hammes Ferry, Carterhaven, IL 62290

Phone: +8557035444877

Job: Forward IT Agent

Hobby: Fishing, Flying, Jewelry making, Digital arts, Sand art, Parkour, tabletop games

Introduction: My name is Otha Schamberger, I am a vast, good, healthy, cheerful, energetic, gorgeous, magnificent person who loves writing and wants to share my knowledge and understanding with you.