Section 4.2 Machine Instructions
The AVR instruction set for 8-bit microcontrollers [16.15], which is used for the ATmega328P microcontroller, has approximately 130 unique instructions. The word size of each instruction is 16 bits. \(\lceil \log_2(130)\rceil = 8\text{,}\) which means that at least 8 bits are required in an instruction to differentiate between each one. This would leave only 8 bits to express each operand. There are 32 general purpose registers that can be used to temporarily store data and many instructions exist that require the contents of two of these registers. In that case, 8 bits is insufficient to properly address both of these registers (each of which requires 5 bits to address).
To get around this limitation, the AVR instruction set uses the concept of variable length instructions, or expanding opcodes. Instructions that have many or lengthy operands are designed to have short opcodes while instructions with few or no operands are designed to have long opcodes. Most AVR instructions are 16 bits, with a few 32-bit instructions used as needed. There are 32 general purpose registers, and the ATmega328P additionally has 32,768Β bytes of program memory and 2,048Β bytes of data memory, which need to be addressed. In addition, there are other specialty registers such as a status register and stack register that can be affected by machine instructions.
While expanding opcodes allows for much greater flexibility in instruction operands, it also makes for more difficult instruction decoding. This is because there is no longer a fixed position and length for each opcode within each instruction.
To highlight the use of expanding opcodes, consider the following AVR instructions which run the gamut from having a long opcode to having a short opcode.
-
The instruction
CLIis used to clear the global interrupt flag in the status registerSREG. Because this instruction requires no operands, the full 16 bits of instruction are used to store the opcode. -
The instruction
NEGconverts the contents of a single general purpose register into a twoβs complement number. Because there are 32 general purpose registers, 5 bits are required for the operand, leaving 11 bits remaining for the opcode. -
Most instructions have two general purpose registers as operands. For example, the instruction
ADDwill sum the contents of two general purpose registers. 10 bits are required to address both of the operands, leaving 6 bits for the opcode. -
A few instructions require very long operands. In order to properly address up to 4Β MB of memory, it is necessary to use 22 bits of data for the operand. In order to accomplish this, a 32-bit instruction is used. 22 bits are dedicated to the memory address with the other 10 bits used for the opcode.
