Only 0.001% of People Know How to Talk to the Little Man Inside a Microcontroller (Atmega328p)
by BoboacaC in Teachers > Pre-K
94 Views, 1 Favorites, 0 Comments
Only 0.001% of People Know How to Talk to the Little Man Inside a Microcontroller (Atmega328p)
Inside every microcontroller, there is a tiny invisible worker: the register little man.
- He is very diligent, but he doesn’t understand abstract words like digitalWrite, TCCR0A, or other complex functions.
- All he knows are the numbers of the drawers in the microcontroller: the registers and memory slots.
- The little man reads what is written in the program by the compiler, that is, the instructions translated from the programmer’s code.
- In practice, the little man does not know what “turn on an LED” means: he just opens drawer 27, writes 128, checks another drawer, step by step.
Supplies
Arduino nano or UNO ,usb cable , pc or phone that support webusb
A Frightening Reality: Less Than 0.001% of Humanity—Know Turning on a LED Entirely in Bare-metal ASM
Do you want to tell the little man inside the microcontroller to turn on the LED? It sounds easy, but for my grandma, a child, or a curious person with no experience, the first obstacle is often just installing the first program: the IDE. An IDE is a special program where you write instructions for the microcontroller, and then it helps you send them to the little man so he can start working.
IDE programs are often very large—sometimes several gigabytes—and they need to be fully installed and initialized before you can even start. For people who are not used to this, it can feel overwhelming and confusing, which is why many give up before even writing a single line of code.
And there’s good news: there’s a solution! A web-based compiler and uploader makes it super easy. Just open this page: https://costycnc.github.io/avr-compiler-js/, write your code, compile, and upload it to your Arduino. Soon, the little man will start opening the drawers you programmed and work for you.
Here’s something truly shocking:
The Earth has nearly 8 billion people, yet only about 40–80 million of them can program—that’s barely 0.5% to 1% of humanity.
Out of those, only a tiny fraction—about 1–5%—know how to speak directly to a microcontroller in its native language: pure assembly, bare metal. That’s just 0.4 to 4 million people worldwide, or between 0.005% and 0.05% of all humans.
And if we go even further… only about 30% to 50% of those assembly programmers have ever done something as “simple” as turning on a LED entirely in bare-metal ASM. That’s only 30,000 to 100,000 people on the whole planet—less than 0.001% of humanity.
And here’s the real shocker: we’re not talking about a niche, highly technical field like chemistry or molecular physics. This is everyday computing, the invisible technology that runs our lives. Yet almost no one truly understands how it works at the most basic, fundamental level.
This is extremely alarming. If one day computing spirals out of control, only a few people will be able to take real action. Those who only know abstract, high-level programming won’t be much help.
Starting from bare metal, learning ASM, and understanding how a machine really works is a path that only about 1 in a thousand programmers even dares to follow. Imagine how few top-quality programmers that produces. These are not just coders—they are the people capable of truly mastering computing from the ground up.
It’s like a mechanic who doesn’t understand how an engine works—a serious warning sign in the world of programming.
How the Little Man Works With Unoptimized Abstract Functions
When the programmer shouts a complex, unoptimized function:
- The compiler translates everything into ASM for the little man.
- The little man opens drawer after drawer, even unnecessary ones, updating registers and memory.
- Result: he works hard, the processor overheats, the fan spins at maximum, and programs slow down.
Optimized function means that the code is written or translated in a way that tells the little man to open only the strictly necessary drawers, reducing work, time, and resource usage.
The compiler is a cold, impartial translator:
- It takes the abstract words shouted by the programmer and converts them into simple instructions that the little man can understand.
- It doesn’t decide anything and doesn’t optimize by itself: it simply converts complex functions into sequences of drawer numbers and elementary operations.
- If there are overlapping libraries or unnecessary instructions, the little man will still execute them because the compiler translated them that way.
How to Help the Little Man Work Better
How to help the little man work better
- More little men in parallel: like a multicore CPU, dividing the work.
- Optimized code: write ASM or efficient code that tells the little man to open only the strictly necessary drawers, avoiding unnecessary operations.
In short: knowing how the little man reads the program and how the compiler translates it allows us to write more efficient code, reduce unnecessary work, and get better performance.
Arduino DigitalWrite() Vs. Bare-Metal AVR Assembly: Efficiency Comparison
Arduino code :
Assembly code:
A long sequence like:
Hex file: 2059 bytes on disk.
File hex:
Includes internal checks, register management, and Arduino function handling. High overhead, less efficient in terms of space and time.
Pure Assembly bare metal avr atmega328p code:
Single instruction that directly sets bit 5 of register 5. Maximum efficiency, minimal overhead.
File hex:
In another words this is effective code :0600D000259A2D9AFDCFD8
This comparison demonstrates the difference in efficiency between using Arduino’s digitalWrite() function and direct AVR assembly instructions (sbi) on an ATmega328P.
- Arduino digitalWrite(LED_BUILTIN, HIGH);
- Generates a long sequence of assembly instructions, including internal checks, register handling, and Arduino function calls.
- Example hex file size: 2059 bytes.
- Comment: High overhead leads to lower efficiency in both time and memory usage.
- Bare-Metal Assembly using sbi
- Directly sets the target bit in the register with a single instruction: sbi 4,5.
- Example hex file size: 624 bytes.
- Comment: Maximum efficiency with minimal overhead, significantly smaller and faster than digitalWrite().
This highlights the trade-off between ease-of-use in Arduino’s high-level API and performance optimization achievable with low-level assembly.
The Little Man and the LED
Imagine the little man inside the microcontroller facing a simple task: turning on an LED.
- When the programmer shouts digitalWrite(LED_BUILTIN, HIGH);
- The compiler translates it into hundreds of instructions.
- The little man does exactly what he is told, drawer after drawer.
- He doesn’t know which steps are unnecessary; he just follows the instructions faithfully.
- The result? He works hard, the processor heats up, and the program takes more time and memory than needed.
- When the programmer whispers sbi(PORTB, 5);
- The compiler gives him one simple instruction:
- “Open drawer 5 and set bit 5. Done.”
- The little man flips the switch immediately, using minimal effort, and the program stays fast and small.
Lesson for the Programmer
- The little man is obedient, not smart: he can’t decide what is necessary or unnecessary.
- Inefficient code is our fault: making him do extra steps is wasted effort.
- Optimized code = efficiency: fewer drawers, less work, faster programs, smaller memory footprint, cooler processor.
Are You Ready to Talk to the Little Man? 🧑🔧
Now that you know who the little man inside the microcontroller is, how the compiler turns your words into numbers, and how much difference there is between “convenient but heavy” functions and direct, optimized instructions… you’re ready to talk to him.
- You know the compiler is a cold translator: it doesn’t understand meaning, it just converts your commands into basic steps.
- You know the little man is diligent but obedient: he does everything you say, even unnecessary tasks.
- You’ve seen the difference between Arduino’s digitalWrite() (easy to write but hundreds of steps) and a single sbi assembly instruction (direct, fast, lightweight).
- You understand efficiency is up to you: fewer “drawers” to open = less work, less heat, less memory use.
💡 Moral: every time you program, you’re giving orders to a tiny worker who never stops. Writing optimized code means respecting his time and energy, and getting a faster, cleaner system.
📌 Next step: open the web compiler (https://costycnc.github.io/avr-compiler-js/), write a simple command, and start speaking his language.
LED ON: Speak His Language
Let’s tell the little man inside the Arduino to turn on the onboard LED (pin D13). We will speak his language using direct instructions.
1. Find the pin in the datasheet
- Open the ATmega328P datasheet (page 280).
- Locate Arduino pin D13, which is PB5 (Port B, bit 5).
2. Write the instructions for the little man
The little man only knows numbers in drawers (registers) and instructions in his “book”:
- First: set the pin as output
- Then: write HIGH to the pin
3. How the little man reads them
- Write in Assembly – we write the instructions in the exact form he understands (sbi 4,5 and sbi 5,5).
- Compile to machine code (hex) – the web compiler converts the Assembly into numeric instructions, like a page number and a slot number in his book.
- Upload to the microcontroller – with web uploader using WebUSB, the little man gets the book with the new instructions.
- Execution – the little man opens the drawers and flips the bits exactly as written: first sets the pin as output, then sets it HIGH.
The little man doesn’t know “turn on LED”; he just follows the book efficiently and immediately.
Upload & LED OFF 💻➡️💡
- Open the web compiler: https://costycnc.github.io/avr-compiler-js/
- Make sure your Arduino is connected via USB to your PC.
- Click Upload to Arduino.
You will see the LED turn on, just like in the video.
- Now, change the instruction:
- Click Upload again. The LED will turn off, just like in the video.
What this teaches you
- This is the first small step in a long journey.
- Assembly language alone won’t help much for complex programs.
- Understanding registers gives you a huge advantage later when using complex IDEs with abstract instructions.
- Don’t forget: if you managed to turn on a LED in bare metal, you are among 0.001% of humanity who know how to do this!