An assembler actually does two important but separate things to help the programmer. One, which you mentioned, is to convert instruction mnemonics into opcodes, based on the addressing mode (e.g., LDA #3 to A9 03 or LDA $1005 to AD 05 10—note the different opcodes for loading an immediate value versus loading a value from a memory address).
But the other, which actually saves a lot more work, is to assign addresses to code and data and do address calculations based on those assignments. So in the following example:
ORG $1000 LDX #$FF loop: STX myvar DEX BNE loop RTS myvar DB $00 the assembler is calculating the addresses which the programmer refers to as loop and myvar, so that the programmer doesn't have to do this himself. In this example, loop will be at $1002 and myvar will be at $100A, but both of those would change if the programmer added another instruction between the start of the program and loop. Further, some of the calculations are not as easy to do as the one above: the BNE loop is translated to D0 FA where the FA is a negative offset from the start of the location after the BNE and its argument.
So 8-Bit Show And Tell making a distinction between:
- assembly: computer-calculation of addresses and opcodes (
STX myvar); - machine language: hand-calculation of addresses with mnemonic translation (
STX $100A); and - machine code: hand-calculation of addresses and opcodes (
8E 0A 10).
Because this three-part distinction isn't so often made, many people use "machine language or machine code" interchangeably for the last one, or perhaps either of the two. The middle one is sometimes referred to as a form of "assembly": on the Apple II with original ROMs, for example, you use the "mini-assembler" for that. Given what 8-Bit Show and Tell is trying to demonstrate, I find his terms reasonable; he just would have done better to explain that when using a "full" assembler, it's not the mnemonic translation that (though useful) is the most important thing, but the address assignments and calculations.