# What does machine code actually look like while being run?

When machine code is actually being executed by hardware and the CPU, what does it look like?

Would it look like binary, as in instructions being represented by ones and zeros, or would it be something made up of hexadecimal digits where opcodes are bytes presented as hex numbers which can be broken back down into binary numbers, like bytecode?

• What you would see are wires, gates, and registers flickering on the silicon. For example, visual6502.org/JSSim Jun 23, 2018 at 4:47
• @Nayuki I think this visualization is awesome and deserves to be made into an answer! Jun 23, 2018 at 4:53
• It doesn't look like anything to me Jun 23, 2018 at 14:32
• It doesn't really even exist at when it's really "executed". It's "JIT compiled" by a (hardware!) device on the CPU to microcode, which actually instructs the CPU! Jun 23, 2018 at 18:06
• One quick way to understand how a computer translates is to build one from logic gates, I really likes watching the one made by Ben Eater youtube.com/playlist?list=PLowKtXNTBypGqImE405J2565dvjafglHU Jun 23, 2018 at 20:25

The best answer I can give is, it doesn't really "look" like anything. The instruction currently being executed by the CPU is represented by a series of wires, some of which have a high voltage, some of which have a low voltage.

You can interpret the high and low voltages as zeroes and ones, but you can equally well interpret groups of high and low voltages as hexadecimal digits, or as an assembly instruction like ADD $0$1 (which is closest to how the CPU interprets it). These numbers and mnemonics themselves are conveniences for humans to read; internally, it's nothing but voltages on wires.

Out of these options, binary is "closest to the metal", in that the zeroes and ones map directly to the high and low voltages on the wires. But none of the others are incorrect, and they're frequently more useful: there's a reason people look at hex-dumps of executables, but almost never binary-dumps.

• So, could you open a program in a hex editor, and do those bytes represented in hex translate to machine code binary which can be ran by a voltage assigned to zero, and a voltage assigned to one? Jun 23, 2018 at 19:01
• @TimHardly Yep! Hex is just easier to read. Assembly, similarly, is even easier to read, but can be translated mechanically to zeroes and ones. That's why assemblers are easier to write than compilers. Jun 23, 2018 at 21:09
• thanks, this whole question has expanded my knowledge and cleared my confusion. Jun 24, 2018 at 2:11
• @TimHardly An assembler just maps a sequence of characters like "NOP" to a series of bits like "10010000", over and over, to turn an assembly file into machine code. The opcodes are determined by the CPU, since it's the part that's going to actually be using them. All computers which can run the same executables do indeed have the same set of opcodes; the x86 set is the most common, and is used in pretty much all PCs nowadays. Another common one is MIPS, used in a number of game consoles. Jun 24, 2018 at 2:47
• @TimHardly If your question is, can the assembler ask the CPU what its opcode is for the NOP instruction, the answer is no. The assembler already has to know what byte to output for the instruction before it can work. In fact, an assembler can output a program for one processor, while itself running on a different processor type. Jun 24, 2018 at 7:32

"Look like" implies a metaphor. If we take "what will it look like" literally, it's going to look like a fancy etched piece of silicon sitting on its motherboard. Clearly metaphor was the goal. To build the metaphor, we need to look at what it really is first. Then we can build a metaphor that is acceptable. This is a bit long, but fortunately, it ends with a video metaphor for you.

The machine code is actually stored in memory as bits. Memory chips are typically DRAM, which stores those bits as voltages across a capacitor and electrons. The two are connected -- its hard to talk about the voltages without the electrons. Sometimes its convenient to talk about one or the other, but understand that where one goes, the other follows.

The journey of machine code starts with a "fetch." A particular pattern of voltages is applied to the wires of the RAM chip indicating that this particular set of bits should be sent to the CPU. Why? Don't know don't care. Typically that signal is sent because the CPU finished the last instruction and is asking for a new one as an instinctive response, like a dog asking for a second treat after you gave it the first one. This process starts off with some primordial kick in the pants caused by a natural instability in the CPU. When a power supply applies a constant voltage to the chip, the rises in voltage eventually lead to the CPU putting the correct voltages on the RAM chips to go get the first instructions (I'm handwaving the BIOS layer a bit, because its not important to the story. Look it up).

Modern memory streams data in parallel. This means the bits that make up the machine code are split up into "lanes" (32 or 64 are common) which is the logical way of saying the 32/64 wires from the RAM to the CPU. The voltage on those lines is raised and lowered as needed to transmit it into the CPU.

Once its in the CPU it can go do its work. This is the realm of microarchitecture, and it can get complicated because this is literally a billion dollar industry. Those voltages affect transistors, which affect other voltages, in ways which we might describe as "adding bits" or "multiplication." They're really all just voltages that represent those bits, in the same way we might scribble the 5 character string "2+2=4" on a piece of paper and say we did mathematics. The pencil graphite is not the number two. It's just the physical representation we're using for that number.

So that's what the real system does, at a tremendously high level. I've skipped well... pretty much everything... but it's decent enough to be able to get back to your actual question. What would it [metaphorically] look like?

As it so happens, I think Martin Molin may have constructed the best metaphor, with his Marble Machine. The machine code is encoded (by hand) onto some Lego Technics strips in the middle as pegs, rather than voltages on a capacitor. This is more like EPROM than DRAM, but both hold data. The marbles are like the electrons, being moved about by voltages (or gravity, in the case of marbles). And as the electrons move, they apply force to gates which do things.

His machine is simple, compared to a modern CPU, but it's not all that bad, as far as metaphors go. And it's catchy!

• The marble machine is too simple for this in the video. A CPU needs state. Jun 23, 2018 at 10:00
• @ThorbjørnRavnAndersen True. I suppose if the marble machine had a few gates which let it throw the levers automatically instead of Marin having to flip them, it'd be closer. Jun 23, 2018 at 14:16
• Thanks! Similar to the question I had asked on the reply above this one, would assembled Assembly code be considered machine code that is translated into voltages and things? Jun 23, 2018 at 15:33
• @TimHardly Using the only meanings for "assembled," "Assembly," and "Machine Code," The product of assembling Assembly is defined to be machine code (so yes, it can be considered to be that =) ). Something that might help is that both assembly and machine code are considered "logical" concepts, closer to the mathematical concept of "2+2=4" and further from the graphite on the paper upon which that equation is written. Assembly/machine-code is assembly/machine-code whether it is being stored on a magnetic disk, written on a piece of paper, or stored in capacitors in DRAM. Jun 23, 2018 at 16:05
• If I may wax philosophic, machine-code is machine-code because we treat it like machine-code. We think of it as machine code. I can point a CPU at the bytes describing a sound in .wav format, and it will indeed execute them as machine code. The resulting execution is not likely to do anything useful (because the sound was not constructed to be machine code), and it may halt, but it could be executed. Jun 23, 2018 at 16:07

Check out this video, in particular 1:00 to 1:17. That's exactly what it looks like when a program is running on a computer. The two rows of lights show the current contents of the address register and the data register. The PDP-11 doesn't have an instruction register, but if there were one and there were lights on the front to show its contents, it would look pretty much the same. 16 lights- some of them on, some of them off.

If you really liked flashing lights, you could have more lights to show the current contents of the six registers, the stack pointer, the program counter... for a further 32768 lights you could have a light for each bit of the cache. You could even have a light for each bit of memory... but that really would be a lot of lights.

This is a PDP11-70 which runs at 15.2 MHz, and each instruction takes about 1.5 microseconds to execute. The human eye can detect changes down to 1/10 second, and in that time, the PDP-11 can execute 60,000 instructions. Basically, everything is a blur.

The hardware designers implementing and testing (and testing and testing) the processor actually do use visual models to see what their designs are doing. Most (if not all) HDL simulation tools output wave views of all of the registers and wires to allow for easy debugging. The screenshot below (taken from here) shows these waves from the VCS simulator for a RISC-V processor running a few instructions.

This is a pretty simple example that shows a small subset of the logic involved in a full processor design. You could open these views up for the entire processor and watch the data propagate through the logic. If you want to see the machine code running, as you mentioned, you could look at the waves for the instruction register or the bus the processor uses to read the instructions out of memory. Most wave viewers have flexible viewing options for buses and registers that let you display their values as binary, hex, octal, and even as enum labels. In some, you can even define your own functions for mapping bit patterns do displayed values.

It's worth noting that this is just a representation of a simulation of the processor. There's no way to get these kinds of views for an already-fabricated processor chip.

Imagine a blind man stumbling down a alley under construction. Everywhere there are holes and rifts, so naturally he should fall. Not this blind man, for he has a paper scroll with instructions, when to wait, when to move, where to move and how to manipulate his environment to reach the end of the road. That is what assembly is, a blindly followed lists of instructions- they only make sense for this alley and for this blind man. You can in theory even reconstruct a 3d model from the instructions alone (Decompiling).

Every change to the platform, make it necessary to recompile the instructions for the blind man. You need to know the hardware(the layout of the construction site), the human typed intention instructions (High Level Code ) like "I want you to jump over all fences you encounter in a row until you haven 12 fences behind you" and the abilitys of the blind men (CPU). Does he have short term memory, the ability to do several things at once?

Taking all these informations and forging a coherent instruction scroll is the job of the compiler.

So can i describe how a programm looks? No. But can we describe how it would feel to execute it? Yes, it would feel like a jump and run, like mirrors-edge without seeing something, following a precise list of instructions, wherever it may take you.