7
The electronics/logic behind "while(1)" and "for(;;)
(piefed.blahaj.zone)
Welcome to the C community!
C is quirky, flawed, and an enormous success.
... When I read commentary about suggestions for where C should go, I often think back and give thanks that it wasn't developed under the advice of a worldwide crowd.
... The only way to learn a new programming language is by writing programs in it.
๐ https://en.cppreference.com/w/c
Programming languages are very far removed from what's actually going on.
You could express the do forever loop as label: startofloop Workload Goto startofloop
If you want the details: you just put the instructions pointer back to the start of loop and get the stack in that state, too.
But the use of goto is generally discouraged. Please note that some programming languages allow the compiler to do anything they want if there is an infinite loop, even texting your ex. (This is for optimization reasons and not maliciousness)
Thanks! I know that I sometimes unreasonably obstinately try to link hardware and software in my mind, but that's just my niche... I love the idea, the notion, that some assembler or interpreter at some point gives a CPU instructions in a format that is impractical for humans to read, which then turns into electrical signals. salivating
Thanks for the headsup! I think they cover ex texting in the next chapter of The C Programming Language, Shiny Edition.
It might be helpful to understand the connection between hardware and software better. There are various ways we can create something that a machine can interpret that have evolved over time. We group these into "generations."
Generation 1: writing machine code directly. Either using things like punch cards, or typing in the 1s and 0s directly (more likely hex code, but close enough). This is difficult and error prone, because it's hard for us to make sense of it. So we came up with...
Generation 2: human-readable machine instructions (aka assembly). We write code in something that's easier for us to understand, but it's still explicit instructions to the processor. Then we use a software tool (an assembler) to convert that to machine code. Assembly is still specific to the processor and requires knowledge of exactly what registers are available and such. And then we thought: what if we could write software in a generic way that could work on any processor? So we came up with...
Generation 3: procedural code. With this, we create a new language that is independent of any processor, which means we're not giving direct instructions anymore. Instead, we specify a general procedure, and that generic code is passed through a new tool (a compiler) which converts the generic code to processor-specific instructions. When people say "I'm a programmer" they usually mean Gen 3 programming.
There are additional generations, but this should help provide a background as to why a language like C exists and how it relates to the actual hardware.
A statement like
while (1)might not seem terribly elegant, but that's because it probably wasn't anticipated to be a common use case when the language was created. A normalwhileloop would likely be converted into something like ajnz(jump if not zero) instruction, checking the result of the argument, but any modern compiler would likely convertwhile(1)to a simplejmp(jump, no conditions) instruction.I understand your fascination with the point where software and hardware meet. I did my undergrad in electrical engineering, and there was one class where we used a simulator to take transistors (the simplest eletrical "switches"), build logic gates from the transistors, then build processor components like registers and a math processor from the logic gates, then finally a simple calculator out of those components. Super cool.
Thank you so much for this! You just understood exactly what I meant, felt and what I was wondering about. ๐
That part on generation 3 was especially enlightning, since it finally makes sense to me why there is a compiler "in between" the procedural code and the assembler. Question: does the assembler come somehow embedded with the hardware/CPU and receives the gen 3 code from the compiler, is the assembler packaged with the compiler or is the assembler a part of the operating system?
Thanks for the clarification on how while(1) could be translated into instructions!
I was already interested in the transition from software to hardware, and then that grew into fascination after reading Code: The Hidden Language of Computer Hardware and Software by Charles Petzold.
Assemblers can come from the CPU manufacturer, but they can also come from a third party. They're most often bundled into the compiler, since it's rare to need to compile without also assembling (many compilers skip the assembly step and convert directly to machine code). There's actually a third tool involved I didn't mention, which is a Linker (takes pieces of machine code and combines them together, so you can separate your software into different parts).
Some CPUs are more niche, and the assemblers/compilers for them sometimes are created by the manufacturer. But there are a few "standard" processor architectures that many CPUs follow, and because they're common between many brands of CPU (and the architectures are published and well known), the compilers are often created by third parties. And there are some compilers (like gcc) that can compile to dozens of different architectures.
As an example, you might have heard terms like
x86,x86_64,armv7, orRISC-V-- these are all processor "architectures", which means that any processor that meets a particular architecture can run machine code built for that architecture. Currently, x86/64 architectures are common among desktops and most laptops (Intel and AMD processors), while ARM architectures are common for tablets and phones and some laptops (Snapdragon processors, for example).