Assembly language provides what is called an abstraction of machine code. When using assembly, programmers do not need to know the details of what numbers mean to the computer, the assembler figures that out instead. Assembly language actually still lets the programmer use all the features of the processor that they could with machine code. In this sense, assembly language has a very good, rare trait: it has the same ability to express things as the thing it is abstracting (machine code) while being much easier to use. Because of this, machine code is almost never used as a programming language.