https://github.com/vegesm/c72 Skip to content Sign up * Product + Features + Mobile + Actions + Codespaces + Packages + Security + Code review + Issues + Integrations + GitHub Sponsors + Customer stories * Team * Enterprise * Explore + Explore GitHub + Learn and contribute + Topics + Collections + Trending + Learning Lab + Open source guides + Connect with others + The ReadME Project + Events + Community forum + GitHub Education + GitHub Stars program * Marketplace * Pricing + Plans + Compare plans + Contact Sales + Education [ ] * # In this repository All GitHub | Jump to | * No suggested jump to results * # In this repository All GitHub | Jump to | * # In this user All GitHub | Jump to | * # In this repository All GitHub | Jump to | Sign in Sign up {{ message }} vegesm / c72 Public * Notifications * Fork 1 * Star 17 The first C compiler ported to x86 17 stars 1 fork Star Notifications * Code * Issues 0 * Pull requests 0 * Actions * Projects 0 * Wiki * Security * Insights More * Code * Issues * Pull requests * Actions * Projects * Wiki * Security * Insights This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository. master Switch branches/tags [ ] Branches Tags Could not load branches Nothing to show {{ refName }} default View all branches Could not load tags Nothing to show {{ refName }} default View all tags 1 branch 0 tags Code Latest commit @vegesm vegesm docs ... e151588 Jun 13, 2021 docs e151588 Git stats * 12 commits Files Permalink Failed to load latest commit information. Type Name Latest commit message Commit time docs docs Jun 13, 2021 examples docs Jun 13, 2021 src make cr a whitespace Jun 12, 2021 test update tests Jun 12, 2021 .gitignore added Makefile and linux support Jun 8, 2021 Caldera-license.pdf regtab ready May 15, 2021 Makefile added Makefile and linux support Jun 8, 2021 README.md docs Jun 13, 2021 c72 c1 output file is given as cl arg Jun 9, 2021 cvtab.sh added Makefile and linux support Jun 8, 2021 fix_tab.sh regtab ready May 15, 2021 test.sh update tests Jun 12, 2021 View code c72 Usage Differences to modern C Internals README.md c72 A port of the earliest C compiler to x86. The compiler generates 32-bit code and works on modern Linux with a current libc. It follows the architecture of the original implementation closely, keeping the bugs and missing features. Usage To compile the compiler: # install 32-bit libraries sudo apt-get install gcc-multilib make ./c72 examples/fizzbuzz.c fizzbuzz ./fizzbuzz Note: if you get errors on missing "bits/libc-header-start.h" headers make sure you have the 32bit libc installed. I've also attached an early implementation of cp from UNIX v5. It worked with minor modifications with this compiler, on my Ubuntu 18.04. It's pretty neat, to have a nearly 50 years old code compile with a nearly 50 years old compiler and run on a modern OS! Differences to modern C This version of C is from around 1972. While the general syntax is pretty much the same as today, there are tons of missing features: * no preprocessor, no for loops * bitwise NOT and XOR is not implemented * no short-circuiting AND and OR * even though there is a keyword for float and double, floating point calculations are not implemented, you can not even write a floating point literal * the type system is very weak: pointers, chars, ints can be freely converted into one another * types of the function parameters are not checked, anything can be passed to any function * compound assignment operators are reversed, they are =+, =* * only integer global variables can be defined, and the syntax is strange: /* defines globalvar to have the value of 2 */ globalvar 2; /* equivalent to int globalarr[]={1, 2, 3}; */ globalarr[] 1, 2, 3; * variable names can be of any length but only the first 8 characters are used; i.e. deadbeef1 and deadbeef2 are effectively the same variables Internals The compiler has two stages: c0 and c1. c0 parses the input C file and generates a half-assembly half-parsed syntax tree temporary file. It is not meant to make the second stage easily portable, rather the memory restrictions of the PDP-11 made the split necessary. Then c1 generates the final assembly, translating the syntax trees to actual code. c0 is a fairly straightforward parser. One interesting bit is that a [b] is parsed and then converted to *(a+b) already in this very early version of C (if you are not familiar with the C standard, a[b] is defined to be equivalent to *((a)+(b))). c1 uses a set of code-generation tables to create the final assmebly. For example, addition is defined as: %n,aw F add A2,R The part starting with % is the pattern the syntax tree has to match. This pattern means the first operand can be anything (n), the second operand is a word sized (w) variable (a - addressible). Then the code generation instructions say that calculate and place the first operand in the current register (F), and create an add instruction where the source argument is the address of the second operand (A2) and the target argument is the current register (R). For example, the C code 2+x would generate the following assembly: mov $2, %eax add 4(%ebp), %eax Here I assumed that x is the first parameter of the function so it is placed right after the stack frame. If you are interested in a more in-depth description see Dennis Ritchie's A Tour through the UNIX C compiler. Although it is for a newer version with some differences, it is still helpful to understand c1. About The first C compiler ported to x86 Resources Readme Stars 17 stars Watchers 2 watching Forks 1 fork Releases No releases published Packages 0 No packages published Languages * C 86.3% * Assembly 11.1% * Shell 2.0% * Makefile 0.6% * (c) 2022 GitHub, Inc. * Terms * Privacy * Security * Status * Docs * Contact GitHub * Pricing * API * Training * Blog * About You can't perform that action at this time. You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.