# How is an Assembly Language Processed by a CPU's Circuitry?

I'd like to have a bit more understanding of how, on a circuitry/hardware level, an assembler program works.

I think I have a very broad-brush understanding of how a CPU would process machine code on a hardware level. Please bear with me for this very generalised, hypothetical example:

If you took 00101110 in machine code, with the first part 0010 as an opcode and the second part 1110 as location address...

I think I understand, broadly, how those 8 bits of data would be fed along 8 wires to an instruction register, and how from there, the opcode 0010 gets fed along 4 wires into a variety of checking circuits to check the opcode, and a checking circuit would output true if if the opcode corresponded to the configuration of that circuit. Like this (yes I've been watching crash course computer science):

And i think I understand how, in broad terms, the location address 0111 would be sent along 4 wires that feed into multiplexors attached to four latch matrices, causing address location 0111 to be accessed in each of those matrices, each of which then feeds back whether its data bit at the location was a 1 or 0 / on or off.

What I'm saying is that I think I can begin to see, or at least imagine, how a processor 'processes' a binary number, on the level of hardware/circuitry, without it seeming like magic.

My question is, can someone explain to me on this level how a CPU, as part of an assembler, would translate assembly code?

For example, how would the circuitry take MOV EAX [EBX] and act on that as an instruction? I know that it would parse it, etc., but HOW does it parse it, on the level of wiring? Like how does it take a 'MOV' and translate that into the correct configuration of on/off wires?

On a related note, obviously the 'MOV' isn't stored as 'MOV' in the computer's memory - it's stored in binary. So if it's already stored in binary, why do we need to bother to translate it to a different binary configuration using an assembler?

• The assembler simply has a table of instructions and opcodes. It's a rather crude piece of software, really (if you disconsider "addons" like macros or optimizations). Describing how the whole process works, however, is too broad a question. Is there some particular concept which would like to ask about that is not already explained, for instance, here? Jun 5 '19 at 7:16
• If you're interested in learning more about CPU design and assembly code a book I would recommend is "Computer Organization and Design" by Patterson and Hennesy. Jun 5 '19 at 9:36
• This is very close to "how does a computer work?" Assembly is converted into machine code by the assembler, and that is what is executed on the CPU. I suggest you research these keywords. Jun 5 '19 at 10:14

An assembler is a program that reads assembly language commands and translates then into a sequence of binary instructions, addresses and data values that is called machine code. The machine code is stored in the computer's memory and can be executed by the computer at some later time. Machine code is read and "understood" directly by the CPU.

So a command such as "load the value 10 into register A" might be written in assembly language as "LDA 10" and then stored in machine code as one byte 00101010. The first four bits of the machine code instruction 0010 represent the LDA instruction and the second four bits 1010 represent the value that is to be loaded.

Note that the assembler makes life easier for the programmer by translating the "LDA" instruction and translating the value 10 from decimal to binary. It will also do other stuff like allowing the programmer to use labels, which it then translates into specific memory addresses.

In the simplest CPU architecture, when the CPU executes the instruction 00101010 it actually runs a sequence of low level microinstructions which will be something like this:

1. Add 1 to the register that tells the CPU where the next instruction is stored in memory
2. Set a control line to take control of the data bus.
3. Load the lowest four bits of the machine code instruction onto the data bus.
4. Release control of the data bus.
5. Set a control line to tell Register A to read and store the value on the data bus.
6. Read the next instruction from memory.

In the very simplest/oldest CPU architecture this final translation from machine code to microinstructions is hard wired in logic gates.

A good guide to this sort of stuff for beginners is "But How Do It Know".

Bonus question: If an assembler is a program that creates other executable programs, how is the assembler created in the first place ?

• Thanks for the link to the book. So I understood all of your reply, with the exception of this section: "An assembler is a program that reads assembly language commands and translates then into a sequence of binary instructions, addresses and data values that is called machine code." My question is, HOW does the assembly program read and translate the command? That's the bit I can't get my head around, and really love to know the detail of how that is performed, on the level of the logic gates - even if it's just a simplified/hypothetical example. Jun 5 '19 at 14:39
• And regarding the bonus question, I guess the first assembler had to be written in machine code? Jun 5 '19 at 14:42
• The assembler has no direct connection with logic gates. It is a program which, like any other program, is ultimately a sequence of machine code instructions. But this particular sequence of machine code instructions tells the CPU how to read lines of text; interpret that text as assembly language commands, data values, addresses, labels etc;. and then translate all that into binary machine code. To create an assembler from scratch you write a very simpler assembler directly in machine code, then use that simple assembler to write an assembler with more functionality and so on. Jun 5 '19 at 14:56
• Another useful resource is the book "The Elements of Computing Systems" amazon.com/Elements-Computing-Systems-Building-Principles/dp/… and the associated web site nand2tetris.org. Jun 5 '19 at 15:03
• Today you write your assembly language with a text editor which captures keyboard input and translates it into Unicode; your computer runs an operating system which stores the output of the text editor as a file on a hard drive; another part of the operating system reads that file and loads it into memory so that the assembler can process it ... Without any of that modern infrastructure the "old school" method used a keypunch machine to encode text as holes on punched cards, and a simple card reader program to read data from cards and load it straight into computer memory. Jun 6 '19 at 8:40

That translation isn’t done by the CPU when it executed the instructions. It is done a lot earlier, when a program called “assembler” translates the assembler instructions into sequences of bits that the CPU can execute.

You say “it’s stored in binary”. Yes, it is translated from assembler to binary, and the binary code is stored.

• Thank you! So how does the translation happen? Isn't it the CPU that performs the translation? How is the translation performed if not through instructions? Jun 5 '19 at 0:43
• The translation of the letters M O V (or most likely the numbers 77 79 86) into a bit pattern can be done by anything that follows rules. It can be me, doing it with pencil and paper. It can be a computer program, running on the same computer, or a different one, long before the time that that bit pattern is ever seen by the CPU as an instruction to be executed. It may make understanding easier if you think of the 77-79-86-to-bits translator as a mysterious alien black box, understand computing in that way, and afterwards see that the “box” is worked by a CPU as well. Jun 5 '19 at 1:25
• Thanks @MartinKochanski. I'm still trying to dig deeper into how, for example, a computer program running on the same computer would translate text input into the binary machine code. Or for, example, let's take the theoretical first ever assembly language. That was presumably written in machine code and then inputted into the computer via a punch card or something similar. But then after that, how would that assembly program running on a computer perform the automatic translation? How for example does automatic parsing work on the level of circuitry? Jun 5 '19 at 14:36
• Punch cards? That's so advanced. It was an egineer in a white lab coat flicking switches to set single bits. Jun 5 '19 at 20:12

The CPU only understands machine code. Assembly language has to be compiled to machine code in order for the CPU to execute it.

Machine code isn't very user friendly. While the very first computers might have been programmed directly in machine code, this has no longer been the case for decades. First, assembly language was invented, and programs, called assemblers, were written that converted assembly language into machine code. The next innovation was higher-level programming languages, that were converted into machine code by a more sophisticated type of program called a compiler. Nowadays we have additional levels of sophistication, like bytecode and virtual machines.

Throughout all this historical development, one thing stayed the same — CPUs only understand machine code, which a compact way of encoding instructions. Modern CPUs typically understand some dialect of an instruction set architecture like x86. There are only a few common instruction set architectures nowadays, and this means that there are many different CPUs which accept, roughly speaking, the same machine code.

The same instruction set architecture could support several assembly languages. For example, there are two different conventions for x86 assembly: AT&T and NASM. Under one convention (AT&T), mov %eax, %ebx means move the contents of the eax register to the ebx register; under the other (Intel), mov eax, ebx implies a move in the opposite direction. The CPU is completely oblivious to such differences, since all it gets to see eventually is machine code. The machine code produced by AT&T mov %eax, %ebx and Intel mov ebx, eax is identical: 89C3 in hex, or 1000100111000011 in binary.

• Cheers. So given that the CPU is oblivious to the differences, how does an assembly program (for example) take input and automatically translate it into binary that's readable by the computer? Do you know how this is done on the level of circuitry? Still trying to understand it on a deeper level. I am probably asking the wrong questions so excuse me, I am a beginner! Jun 5 '19 at 14:38
• It’s not done at the level of circuitry. An assembler is a computer program like any other, for example the browser you’re using to read this. Jun 5 '19 at 14:51
• Ok, so presumably the assembler is stored in memory as binary. What is the process by which that binary translates is able to translate text input into more binary? Does each bit of text input immediately get encoded as a bit of binary, and certain binary patterns will correspond to certain combinations of letters - the assembler program can recognise these patterns and then perform the appropriate operation? Jun 5 '19 at 16:35
• During my BA we had one class in which we had to write an assembler. There’s nothing mysterious about it. It’s just a program. Perhaps you should consider taking such a class. Jun 5 '19 at 16:37
• In any case, you seem to have the wrong image in your mind about how a computer works. This is too broad to explain on this platform. I suggest doing some reading on computer organization. Jun 5 '19 at 16:38