Sorcery in the open: is generated code still source code?

chotchkies1 pts0 comments

Sorcery in the open

Menu

Cameron Hotchkies

7 min read

July 22, 2026

Categories

ai<br>coding

Tags

ai<br>llm<br>opensource<br>reviews

In the 1970s a bunch of academics started complaining when software was only delivered as a compiled artifact. It was<br>kind of ignored by the companies trying to monetize their software, but it was taken up by a small group of people<br>championing free software. By the 1980s, they codified their demands.

Then in the 1990s, the ubiquity of the home computer, mixed with the distribution channel of inexpensive consumer<br>internet brought “free software” to the more common parlance, but “free” is a homonym and most people focused on the<br>money.

Given that the cost to develop mediocre-to-competent level software has dropped to a $20 monthly subscription cost, it’s<br>worth revisiting the other side of the free definition.

The principles behind wanting source code distributed with software are pretty reasonable.

Source code (and steps how to run it) is required if the user wants to repair a flaw. It’s also helpful if the user<br>wants to alter the purpose from the original authors limited intent. Finally, it’s helpful for novices to learn by<br>example.

If you’re here, you probably know what source code is, but let’s take a look at how it’s evolved over time.

The Ancient Ones

At its core, a computer is a yes/no machine. This yes/no, true/false, on/off (footnote: technically the correct one)<br>lends itself to encoding as a base 2 number system. The CPU loads the instruction, then runs it.

The problem here is remembering if “139” was the addition instruction, or was it “2736”? Wait, it’s both, and they’re<br>slightly different.

This is where assembly language came into play. Swap the hard to remember numbers with slightly less hard to remember<br>characters. These characters are the mnemonics and the numbers they represent are the opcodes .

So instead of “139” you write ADD, instead of “2736” you write ADDS. And in both cases you open the manual to<br>remember what the side effect of the second one was.

The program that took the mnemonics and their arguments (whatever you were adding) and translated it to the opcodes /<br>binary was called an assembler , and this was Assembly language.

That 70s code

In the early 1970s, the C language was invented and by the late 1970s it was getting widespread use. There were other<br>languages, but we don’t care about them in this narrative.

What C (and other compiled languages) did was provide a more compact way to express your programs.

// I wake up with zero limes<br>int limeCounter = 0;

// I go to the store<br>limeCounter += 5;

printf(“I have %d limes\n”, limeCounter);

This was a massive reduction in effort, since just the “I go to the store” section is this in assembly:

ldr  w1, [x0]       // load limeCounter<br>add  w1, w1, #5     // +5<br>str  w1, [x0]       // store back

[click here for the full assembly...]

.section __DATA,__data<br>limeCounter:<br>.long 0

.section __TEXT,__text<br>.global _main

_main:<br>// limeCounter += 5

adrp x0, limeCounter@PAGE<br>add x0, x0, limeCounter@PAGEOFF

ldr w1, [x0] // load limeCounter<br>add w1, w1, #5 // +5<br>str w1, [x0] // store back

// printf("I have %d limes\n", limeCounter)

adrp x0, fmt@PAGE<br>add x0, x0, fmt@PAGEOFF

mov w1, w1 // second argument = limeCounter

bl _printf

mov w0, #0<br>ret

.section __TEXT,__cstring<br>fmt:<br>.asciz "I have %d limes\n"

The act of translating the C version to the assembly version is referred to as compiling. You can combine the<br>compilation and assembly steps invisibly, but they are two separate stages.

Consistency not guaranteed

One subtle change introduced by leveraging compilers is that it leaves room for the translator to take some liberties.

In our example, the compiler chose to use the ADD mnemonic, but ADDS would have worked.

An observant reader will also notice that for this simple program, the variable was never used, so the addition<br>operation can be removed, just start the lime counter at 5.

Compilers can, and do, take these liberties. Those are the compiler optimizations. That also means that different<br>versions or brands of compilers generate different resulting outputs.

When someone expects the source code they mean the C version. That is closest to the intent of the author.

Open for interpretation

One downside to compiled languages is that the binaries they produce were tied to the specific CPU they are assembled<br>for. You can write compiled code that could be cross platform but it takes more care and concentration.

In the late 1990s, while the Spice Girls were getting down with their friends, the Netscape team was hard at work.<br>Inside of their web browser (Netscape’s, not the Spice Girls’) was an engine that could read uncompiled code hidden in<br>the webpage that could modify the page itself.

Since the browser would be running on a whole bunch of different CPUs, it also had a different paradigm, the<br>interpreter . Instead of transforming the language to assembly, then assembling, it converted the...

limecounter code assembly software source different

Related Articles