What is opcode


Command structure

Individual program instructions or operations (= machine instructions) are stored in the microcomputer as binary values ​​in the program memory. A distinction is made between operations for data transport, arithmetic operations, logical operations and program control operations. Depending on the type and use, a complete machine command requires 1, 2 or 3 bytes of storage space. The first byte always contains the Opcode (short: opcode). There are a maximum of 256 opcodes in the command scope of an 8-bit µC. Each command cycle always begins with reading and decoding the opcode, which the control unit uses to control the further command steps. In the case of 2- or 3-byte commands, the control unit causes further bytes to be read from the program memory. These are referred to as operands and, in the case of a transport command, contain, for example, the destination and source address for the data to be transferred.

Example: An 8-bit input byte at port 1 (address 90h) of the controller is to be written to the memory location with address 6Eh in the internal RAM. The assembler command for this is:

  • mov 6Eh, 90h; 6Eh = destination address, 90h = source address

Translated into the binary machine code, this command reads:

First the source and then the target operand is shown here. The reverse order applies in the mnemonic representation.
The binary machine codes are converted into a hex code for display purposes. The following hex code results for the example:85 90 6E

First the opcode and then the source and destination addresses of the data are read from the program memory. The memory mapping shows the arrangement of the three command bytes in the program memory. After the command has been executed, the program counter (PC) points to the opcode of the following command.



Addressing types

The 8051 controller knows five different addressing types for access to memory locations, registers and on-chip peripherals. They differ in the number of command bytes required, the command execution time and the possible access targets:

1. Direct addressing

The operand consists of a memory address in the internal RAM. This address is specified as a hex code or symbolically (see above).

Example: mov 48h, 0A0h; Content of Port2 in the internal RAM
mov 48h, P2; dito. With a symbolic address

For direct addressing, one byte is required in the program memory for each operand.

2. Register addressing

With register addressing, the operand consists of one of the special registers: R0 ... R7, A, B, DPTR (16 bit), CY (1 bit).

Example: mov A, R4; Copies the content of the register R0 into the; battery pack

Since these special registers are required very often in the 8051, they are integrated directly into the opcode. There are therefore a total of 8 opcodes for the above command, depending on which of the registers R0 ... R7 is used as an operand:



mov A, R0


mov A, R1


mov A, R2


mov A, R3


mov A, R4


mov A, R5


mov A, R6


mov A, R7


Since all registers of the 8051 are organized in the SFR or internal RAM, each of these registers can of course also be addressed (directly) with its memory address. The above command can also be formulated as follows:

mov 0E0h, 04h; E0 = accumulator, 04 = register R4

The difference between the two types of addressing becomes apparent when you compare the memory requirements and the execution time of the commands. The first example only occupies 1 byte of program memory and is processed in one machine cycle. With direct addressing, three bytes and two machine cycles are required.

3. Immediate addressing

With this type of addressing, the operand consists of a constant in the program memory. Since the program memory can only be changed during programming, but not during runtime, such a constant is of course only permissible as a source operand. The assembler allows different types of representation for constants. However, these are always identified by the # symbol (diamond, double cross or garden fence). The number 65 can thus be represented in the following equivalent forms:







# 65d



# 41h



# 01000001b



# 101o



# 'A'



Address constants can also be defined for addressing:




# 1F00h

Address constant



Example: mov A, # 0; Erases the battery!
mov DPTR, # 1F00h; sets the data pointer to address 1F00h; in the program memory
mov P1, # 01110111b; The bits of port 1 are accordingly; the bit mask occupied

4. Register indirect addressing

Here, the address of the operand is not specified directly in the command, but is read indirectly from an auxiliary register. Serve as an auxiliary register R0 and R1 for access to the internal RAM, as well as the data pointer DPTR for access to the external RAM.

Example: mov R1, # 2Eh; Load R1 with address constant 2Eh
mov A, @ R1; Copies the contents of 2Eh into the battery

Register indirect addressing enables the same code to be executed with different target or source operands.

5.Indicated addressing (base address + index)

Indexed addressing makes it very easy to access data tables, data fields or text constants in the program memory. Here too, of course, only read access is possible. The data pointer (DPTR) or the program counter (PC) is used as the base address. The accumulator serves as the index (or offset). The following example shows how to fetch a table value from the program memory:

Example: mov DPTR, # 02B3h; Loads the address constant 02B3h
; in the data pointer (base address)
mov A, # 02h; Index 02h in the battery
movc A, @ A + DPTR; Get table value from 02B5h

Exercise on command structure and addressing types: