It's not the assembly language really but the underlying machine language which prevents these operations.
While assembly is made up of easy to read words or mnemonics, they actually represent quite directly the 1s and 0s of the machine code. On x86 CPUs each instruction is typically made up of a sequence of bytes with individual bytes or even bits within the bytes having meaning. Certain bits represent the instruction, others represent the addressing mode. In register addressing modes such as your examples some bits represent which specific registers are to be used as the source and destination of the mov instruction.
Now the x86 family of processors go back a long way to the 1970s when CPU architecture was simpler. In those days the concept of the accumulator was of key importance - ax is the 16-bit x86 accumulator. All calculations were built up or "accumulated" in this register so it was available to all instructions. Other general purpose registers had a more restricted range of use.
Because instructions were based on bytes you wanted as few bytes to represent an instruction as possible to keep instruction decoding fast. To keep as many instructions as short as possible the use of the accumulator is made central.
On more modern CPUs such as the Motorola 680x0 more general purpose registers have more abilities that were previously the domain of the accumulator. On RISC CPUs all registers are as flexible as accumulators. I have heard that in 64-bit mode the current x86/amd64 instruction set is now much less restricted.